diff --git a/Makefile.am b/Makefile.am index 23a8b1a6..e940e2be 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,9 +16,11 @@ EXTRA_DIST = RELNOTES LICENSE \ doc/ja_JP.eucJP/dhclient-script.8 doc/ja_JP.eucJP/dhclient.8 \ doc/ja_JP.eucJP/dhclient.conf.5 doc/ja_JP.eucJP/dhclient.leases.5 \ doc/ja_JP.eucJP/dhcp-eval.5 doc/ja_JP.eucJP/dhcp-options.5 \ - doc/examples/dhclient-dhcpv6.conf doc/examples/dhcpd-dhcpv6.conf + doc/examples/dhclient-dhcpv6.conf doc/examples/dhcpd-dhcpv6.conf \ + util/bind.sh util/bindlib.sh util/bindcus.sh \ + bind/bind.tar.gz bind/version.tmp -SUBDIRS = includes tests common minires dst omapip client dhcpctl relay server +SUBDIRS = includes tests common dst omapip client dhcpctl relay server nobase_include_HEADERS = dhcpctl/dhcpctl.h diff --git a/README b/README index ca11c348..5b0b3e8a 100644 --- a/README +++ b/README @@ -134,6 +134,17 @@ the tar utility and the gzip command - type something like: gunzip dhcp-4.1.0.tar.gz tar xvf dhcp-4.1.0.tar + BUILDING BIND LIBRARIES + +To build the BIND libraries used by DHCP cd to the dhcp-4.1.0 subdirectory +that you've just created and run the bindcus.sh from the the util +subdirectory - something like this: + + sh util/bindcus.sh + +In order to build the necessary libraries you will need to have "gmake" +available on your build system. + CONFIGURING IT Now, cd to the dhcp-4.1.0 subdirectory that you've just created and @@ -150,8 +161,8 @@ your own. DYNAMIC DNS UPDATES A fully-featured implementation of dynamic DNS updates is included in -this release. There are no build dependencies with any BIND version -- this version can and should just use the resolver in your C library. +this release. It uses libraries from BIND and, to avoid issues with +different versions, includes the necessary BIND version. There is documentation for the DDNS support in the dhcpd.conf manual page - see the beginning of this document for information on finding diff --git a/RELNOTES b/RELNOTES index 0d4b8fd9..91cd5cbb 100644 --- a/RELNOTES +++ b/RELNOTES @@ -9,6 +9,10 @@ ISC DHCP 4.2.x includes features that were not included in DHCP 4.1.x. These include: +Processing the DHCP to DNS server transactions in an asyncrhonous fashion. +The DHCP server or client can now continue with it's processing while +awaiting replies from the DNS server. + There are a number of DHCPv6 limitations and features missing in this release, which will be addressed in the future: @@ -71,6 +75,10 @@ work on other platforms. Please report any problems and suggested fixes to calculations. Invalid renew and rebinding times (e.g., greater than the determined lease time) are omitted. +- Processing the DHCP to DNS server transactions in an asyncrhonous fashion. + The DHCP server or client can now continue with it's processing while + awaiting replies from the DNS server. + Changes since 4.1.0 (bug fixes) - Remove infinite loop in token_print_indent_concat(). diff --git a/client/Makefile.am b/client/Makefile.am index f01179ae..77ed0552 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -4,8 +4,8 @@ dhclient_SOURCES = clparse.c dhclient.c dhc6.c \ scripts/bsdos scripts/freebsd scripts/linux scripts/macos \ scripts/netbsd scripts/nextstep scripts/openbsd \ scripts/solaris scripts/openwrt -dhclient_LDADD = ../common/libdhcp.a ../minires/libres.a \ - ../omapip/libomapi.a ../dst/libdst.a +dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \ + ../bind/lib/libdns.a ../bind/lib/libisc.a man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5 EXTRA_DIST = $(man_MANS) diff --git a/client/clparse.c b/client/clparse.c index 4b454e20..c8104bd0 100644 --- a/client/clparse.c +++ b/client/clparse.c @@ -226,7 +226,7 @@ int read_client_conf_file (const char *name, struct interface_info *ip, } while (1); token = next_token (&val, (unsigned *)0, cfile); status = (cfile -> warnings_occurred - ? ISC_R_BADPARSE + ? DHCP_R_BADPARSE : ISC_R_SUCCESS); end_parse (&cfile); return status; diff --git a/client/dhc6.c b/client/dhc6.c index 7363e75f..84a00874 100644 --- a/client/dhc6.c +++ b/client/dhc6.c @@ -744,7 +744,7 @@ dhc6_parse_ia_na(struct dhc6_ia **pia, struct packet *packet, MDL); dfree(ia, MDL); data_string_forget(&ds, MDL); - return ISC_R_BADPARSE; + return DHCP_R_BADPARSE; } } data_string_forget(&ds, MDL); @@ -829,7 +829,7 @@ dhc6_parse_ia_ta(struct dhc6_ia **pia, struct packet *packet, MDL); dfree(ia, MDL); data_string_forget(&ds, MDL); - return ISC_R_BADPARSE; + return DHCP_R_BADPARSE; } } data_string_forget(&ds, MDL); @@ -933,7 +933,7 @@ dhc6_parse_ia_pd(struct dhc6_ia **pia, struct packet *packet, MDL); dfree(ia, MDL); data_string_forget(&ds, MDL); - return ISC_R_BADPARSE; + return DHCP_R_BADPARSE; } } data_string_forget(&ds, MDL); @@ -1039,7 +1039,7 @@ dhc6_parse_addrs(struct dhc6_addr **paddr, struct packet *packet, MDL); dfree(addr, MDL); data_string_forget(&ds, MDL); - return ISC_R_BADPARSE; + return DHCP_R_BADPARSE; } } @@ -1145,7 +1145,7 @@ dhc6_parse_prefixes(struct dhc6_addr **ppfx, struct packet *packet, MDL); dfree(pfx, MDL); data_string_forget(&ds, MDL); - return ISC_R_BADPARSE; + return DHCP_R_BADPARSE; } } @@ -2325,10 +2325,10 @@ dhc6_get_status_code(struct option_state *options, unsigned *code, isc_result_t rval = ISC_R_SUCCESS; if ((options == NULL) || (code == NULL)) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if ((msg != NULL) && (msg->len != 0)) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; memset(&ds, 0, sizeof(ds)); @@ -2341,7 +2341,7 @@ dhc6_get_status_code(struct option_state *options, unsigned *code, NULL, &global_scope, oc, MDL)) { if (ds.len < 2) { log_error("Invalid status code length %d.", ds.len); - rval = ISC_R_FORMERR; + rval = DHCP_R_FORMERR; } else *code = getUShort(ds.data); @@ -2368,7 +2368,7 @@ dhc6_check_status(isc_result_t rval, struct option_state *options, isc_result_t status; if ((scope == NULL) || (code == NULL)) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* If we don't find a code, we assume success. */ *code = STATUS_Success; @@ -2452,7 +2452,7 @@ dhc6_init_action(struct client_state *client, isc_result_t *rvalp, log_fatal("Impossible condition at %s:%d.", MDL); if (client == NULL) { - *rvalp = ISC_R_INVALIDARG; + *rvalp = DHCP_R_INVALIDARG; return ISC_FALSE; } @@ -2478,7 +2478,7 @@ dhc6_select_action(struct client_state *client, isc_result_t *rvalp, log_fatal("Impossible condition at %s:%d.", MDL); if (client == NULL) { - *rvalp = ISC_R_INVALIDARG; + *rvalp = DHCP_R_INVALIDARG; return ISC_FALSE; } rval = *rvalp; @@ -2605,7 +2605,7 @@ dhc6_reply_action(struct client_state *client, isc_result_t *rvalp, log_fatal("Impossible condition at %s:%d.", MDL); if (client == NULL) { - *rvalp = ISC_R_INVALIDARG; + *rvalp = DHCP_R_INVALIDARG; return ISC_FALSE; } rval = *rvalp; @@ -2706,7 +2706,7 @@ dhc6_stop_action(struct client_state *client, isc_result_t *rvalp, log_fatal("Impossible condition at %s:%d.", MDL); if (client == NULL) { - *rvalp = ISC_R_INVALIDARG; + *rvalp = DHCP_R_INVALIDARG; return ISC_FALSE; } rval = *rvalp; @@ -2772,7 +2772,7 @@ dhc6_check_reply(struct client_state *client, struct dhc6_lease *new) int nscore, sscore; if ((client == NULL) || (new == NULL)) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; switch (client->state) { case S_INIT: @@ -2819,7 +2819,7 @@ dhc6_check_reply(struct client_state *client, struct dhc6_lease *new) break; default: log_error("dhc6_check_reply: no type."); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } rval = dhc6_check_status(rval, ia->options, scope, &code); @@ -4392,7 +4392,9 @@ start_bound(struct client_state *client) struct dhc6_addr *addr, *oldaddr; struct dhc6_lease *lease, *old; const char *reason; +#if defined (NSUPDATE) TIME dns_update_offset = 1; +#endif lease = client->active_lease; if (lease == NULL) { @@ -4453,10 +4455,12 @@ start_bound(struct client_state *client) } else oldaddr = NULL; +#if defined (NSUPDATE) if ((oldaddr == NULL) && (ia->ia_type == D6O_IA_NA)) dhclient_schedule_updates(client, &addr->address, dns_update_offset++); +#endif /* Shell out to setup the new binding. */ script_init(client, reason, NULL); @@ -4787,11 +4791,13 @@ do_depref(void *input) piaddr(addr->address), (unsigned) addr->plen); +#if defined (NSUPDATE) /* Remove DDNS bindings at depref time. */ if ((ia->ia_type == D6O_IA_NA) && client->config->do_forward_update) - client_dns_update(client, 0, 0, + client_dns_remove(client, &addr->address); +#endif } } } @@ -4838,6 +4844,7 @@ do_expire(void *input) piaddr(addr->address), (unsigned) addr->plen); +#if defined (NSUPDATE) /* We remove DNS records at depref time, but * it is possible that we might get here * without depreffing. @@ -4845,8 +4852,9 @@ do_expire(void *input) if ((ia->ia_type == D6O_IA_NA) && client->config->do_forward_update && !(addr->flags & DHC6_ADDR_DEPREFFED)) - client_dns_update(client, 0, 0, + client_dns_remove(client, &addr->address); +#endif continue; } @@ -4905,9 +4913,11 @@ unconfigure6(struct client_state *client, const char *reason) client->active_lease, ia, addr); script_go(client); +#if defined (NSUPDATE) if ((ia->ia_type == D6O_IA_NA) && client->config->do_forward_update) - client_dns_update(client, 0, 0, &addr->address); + client_dns_remove(client, &addr->address); +#endif } } } diff --git a/client/dhclient.c b/client/dhclient.c index 1b5189b8..640530a8 100644 --- a/client/dhclient.c +++ b/client/dhclient.c @@ -37,6 +37,7 @@ #include #include #include +#include TIME default_lease_time = 43200; /* 12 hours... */ TIME max_lease_time = 86400; /* 24 hours... */ @@ -134,6 +135,12 @@ main(int argc, char **argv) { setlogmask(LOG_UPTO(LOG_INFO)); #endif + /* Set up the isc and dns library managers */ + status = dhcp_context_create(); + if (status != ISC_R_SUCCESS) + log_fatal("Can't initialize context: %s", + isc_result_totext(status)); + /* Set up the OMAPI. */ status = omapi_init(); if (status != ISC_R_SUCCESS) @@ -1186,9 +1193,10 @@ void bind_lease (client) client -> state = S_BOUND; reinitialize_interfaces (); go_daemon (); +#if defined (NSUPDATE) if (client->config->do_forward_update) - dhclient_schedule_updates(client, &client->active->address, - 1); + dhclient_schedule_updates(client, &client->active->address, 1); +#endif } /* state_bound is called when we've successfully bound to a particular @@ -2676,7 +2684,7 @@ write_duid(struct data_string *duid) int stat; if ((duid == NULL) || (duid->len <= 2)) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (leaseFile == NULL) { /* XXX? */ leaseFile = fopen(path_dhclient_db, "w"); @@ -2724,7 +2732,7 @@ write_client6_lease(struct client_state *client, struct dhc6_lease *lease, } if (client == NULL || lease == NULL) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (leaseFile == NULL) { /* XXX? */ leaseFile = fopen(path_dhclient_db, "w"); @@ -3570,6 +3578,75 @@ static void shutdown_exit (void *foo) exit (0); } +#if defined (NSUPDATE) +/* + * If the first query fails, the updater MUST NOT delete the DNS name. It + * may be that the host whose lease on the server has expired has moved + * to another network and obtained a lease from a different server, + * which has caused the client's A RR to be replaced. It may also be + * that some other client has been configured with a name that matches + * the name of the DHCP client, and the policy was that the last client + * to specify the name would get the name. In this case, the DHCID RR + * will no longer match the updater's notion of the client-identity of + * the host pointed to by the DNS name. + * -- "Interaction between DHCP and DNS" + */ + +/* The first and second stages are pretty similar so we combine them */ +void +client_dns_remove_action(dhcp_ddns_cb_t *ddns_cb, + isc_result_t eresult) +{ + + isc_result_t result; + + if ((eresult == ISC_R_SUCCESS) && + (ddns_cb->state == DDNS_STATE_REM_FW_YXDHCID)) { + /* Do the second stage of the FWD removal */ + ddns_cb->state = DDNS_STATE_REM_FW_NXRR; + + result = ddns_modify_fwd(ddns_cb); + if (result == ISC_R_SUCCESS) { + return; + } + } + + /* If we are done or have an error clean up */ + ddns_cb_free(ddns_cb, MDL); + return; +} + +void +client_dns_remove(struct client_state *client, + struct iaddr *addr) +{ + dhcp_ddns_cb_t *ddns_cb; + isc_result_t result; + + /* if we have an old ddns request for this client, cancel it */ + if (client->ddns_cb != NULL) { + ddns_cancel(client->ddns_cb); + client->ddns_cb = NULL; + } + + ddns_cb = ddns_cb_alloc(MDL); + if (ddns_cb != NULL) { + ddns_cb->address = *addr; + ddns_cb->timeout = 0; + + ddns_cb->state = DDNS_STATE_REM_FW_YXDHCID; + ddns_cb->flags = DDNS_UPDATE_ADDR; + ddns_cb->cur_func = client_dns_remove_action; + + result = client_dns_update(client, ddns_cb); + + if (result != ISC_R_TIMEDOUT) { + ddns_cb_free(ddns_cb, MDL); + } + } +} +#endif + isc_result_t dhcp_set_control_state (control_object_state_t oldstate, control_object_state_t newstate) { @@ -3590,9 +3667,12 @@ isc_result_t dhcp_set_control_state (control_object_state_t oldstate, case server_shutdown: if (client -> active && client -> active -> expiry > cur_time) { - if (client -> config -> do_forward_update) - client_dns_update(client, 0, 0, - &client->active->address); +#if defined (NSUPDATE) + if (client->config->do_forward_update) { + client_dns_remove(client, + &client->active->address); + } +#endif do_release (client); } break; @@ -3616,71 +3696,136 @@ isc_result_t dhcp_set_control_state (control_object_state_t oldstate, return ISC_R_SUCCESS; } -/* Schedule updates to retry occasionally until it no longer times out. +#if defined (NSUPDATE) +/* + * Called after a timeout if the DNS update failed on the previous try. + * Starts the retry process. If the retry times out it will schedule + * this routine to run again after a 10x wait. */ void -dhclient_schedule_updates(struct client_state *client, struct iaddr *addr, - int offset) +client_dns_update_timeout (void *cp) { - struct dns_update_state *ustate; - struct timeval tv; + dhcp_ddns_cb_t *ddns_cb = (dhcp_ddns_cb_t *)cp; + struct client_state *client = (struct client_state *)ddns_cb->lease; + isc_result_t status = ISC_R_FAILURE; - if (!client->config->do_forward_update) - return; + if ((client != NULL) && + ((client->active != NULL) || + (client->active_lease != NULL))) + status = client_dns_update(client, ddns_cb); - ustate = dmalloc(sizeof(*ustate), MDL); - - if (ustate != NULL) { - ustate->client = client; - ustate->address = *addr; - ustate->dns_update_timeout = 1; - - tv.tv_sec = cur_time + offset; - tv.tv_usec = 0; - add_timeout(&tv, client_dns_update_timeout, - ustate, NULL, NULL); - } else { - log_error("Unable to allocate dns update state for %s.", - piaddr(*addr)); + /* + * A status of timedout indicates that we started the update and + * have released control of the control block. Any other status + * indicates that we should clean up the control block. We either + * got a success which indicates that we didn't really need to + * send an update or some other error in which case we weren't able + * to start the update process. In both cases we still own + * the control block and should free it. + */ + if (status != ISC_R_TIMEDOUT) { + if (client != NULL) { + client->ddns_cb = NULL; + } + ddns_cb_free(ddns_cb, MDL); } } -/* Called after a timeout if the DNS update failed on the previous try. - Retries the update, and if it times out, schedules a retry after - ten times as long of a wait. */ +/* + * If the first query succeeds, the updater can conclude that it + * has added a new name whose only RRs are the A and DHCID RR records. + * The A RR update is now complete (and a client updater is finished, + * while a server might proceed to perform a PTR RR update). + * -- "Interaction between DHCP and DNS" + * + * If the second query succeeds, the updater can conclude that the current + * client was the last client associated with the domain name, and that + * the name now contains the updated A RR. The A RR update is now + * complete (and a client updater is finished, while a server would + * then proceed to perform a PTR RR update). + * -- "Interaction between DHCP and DNS" + * + * If the second query fails with NXRRSET, the updater must conclude + * that the client's desired name is in use by another host. At this + * juncture, the updater can decide (based on some administrative + * configuration outside of the scope of this document) whether to let + * the existing owner of the name keep that name, and to (possibly) + * perform some name disambiguation operation on behalf of the current + * client, or to replace the RRs on the name with RRs that represent + * the current client. If the configured policy allows replacement of + * existing records, the updater submits a query that deletes the + * existing A RR and the existing DHCID RR, adding A and DHCID RRs that + * represent the IP address and client-identity of the new client. + * -- "Interaction between DHCP and DNS" + */ -void client_dns_update_timeout (void *cp) +/* The first and second stages are pretty similar so we combine them */ +void +client_dns_update_action(dhcp_ddns_cb_t *ddns_cb, + isc_result_t eresult) { - struct dns_update_state *ustate = cp; - isc_result_t status = ISC_R_FAILURE; + isc_result_t result; struct timeval tv; - /* XXX: DNS TTL is a problem we need to solve properly. Until - * that time, 300 is a placeholder default for something that is - * less insane than a value scaled by lease timeout. - */ - if ((ustate->client->active != NULL) || - (ustate->client->active_lease != NULL)) - status = client_dns_update(ustate->client, 1, 300, - &ustate->address); + switch(eresult) { + case ISC_R_SUCCESS: + default: + /* Either we succeeded or broke in a bad way, clean up */ + break; - if (status == ISC_R_TIMEDOUT) { - if (ustate->dns_update_timeout < 3600) - ustate->dns_update_timeout *= 10; - tv.tv_sec = cur_time + ustate->dns_update_timeout; + case DNS_R_YXRRSET: + /* + * This is the only difference between the two stages, + * check to see if it is the first stage, in which case + * start the second stage + */ + if (ddns_cb->state == DDNS_STATE_ADD_FW_NXDOMAIN) { + ddns_cb->state = DDNS_STATE_ADD_FW_YXDHCID; + ddns_cb->cur_func = client_dns_update_action; + + result = ddns_modify_fwd(ddns_cb); + if (result == ISC_R_SUCCESS) { + return; + } + } + break; + + case ISC_R_TIMEDOUT: + /* + * We got a timeout response from the DNS module. Schedule + * another attempt for later. We forget the name, dhcid and + * zone so if it gets changed we will get the new information. + */ + data_string_forget(&ddns_cb->fwd_name, MDL); + data_string_forget(&ddns_cb->dhcid, MDL); + if (ddns_cb->zone != NULL) { + forget_zone((struct dns_zone **)&ddns_cb->zone); + } + + /* Reset to doing the first stage */ + ddns_cb->state = DDNS_STATE_ADD_FW_NXDOMAIN; + ddns_cb->cur_func = client_dns_update_action; + + /* and update our timer */ + if (ddns_cb->timeout < 3600) + ddns_cb->timeout *= 10; + tv.tv_sec = cur_time + ddns_cb->timeout; tv.tv_usec = 0; add_timeout(&tv, client_dns_update_timeout, - ustate, NULL, NULL); - } else - dfree(ustate, MDL); + ddns_cb, NULL, NULL); + return; + } + + ddns_cb_free(ddns_cb, MDL); + return; } /* See if we should do a DNS update, and if so, do it. */ -isc_result_t client_dns_update (struct client_state *client, int addp, - int ttl, struct iaddr *address) +isc_result_t +client_dns_update(struct client_state *client, dhcp_ddns_cb_t *ddns_cb) { - struct data_string ddns_fwd_name, ddns_dhcid, client_identifier; + struct data_string client_identifier; struct option_cache *oc; int ignorep; int result; @@ -3717,10 +3862,9 @@ isc_result_t client_dns_update (struct client_state *client, int addp, return ISC_R_SUCCESS; /* If no FQDN option was supplied, don't do the update. */ - memset (&ddns_fwd_name, 0, sizeof ddns_fwd_name); if (!(oc = lookup_option (&fqdn_universe, client -> sent_options, FQDN_FQDN)) || - !evaluate_option_cache (&ddns_fwd_name, (struct packet *)0, + !evaluate_option_cache (&ddns_cb->fwd_name, (struct packet *)0, (struct lease *)0, client, client -> sent_options, (struct option_state *)0, @@ -3732,8 +3876,6 @@ isc_result_t client_dns_update (struct client_state *client, int addp, * the client identifier, if there is one, or the interface's * MAC address. */ - memset (&ddns_dhcid, 0, sizeof ddns_dhcid); - result = 0; memset(&client_identifier, 0, sizeof(client_identifier)); if (client->active_lease != NULL) { @@ -3747,7 +3889,7 @@ isc_result_t client_dns_update (struct client_state *client, int addp, * field. We aren't using RFC4701 DHCID RR's yet, * but this is as good a value as any. */ - result = get_dhcid(&ddns_dhcid, 2, + result = get_dhcid(&ddns_cb->dhcid, 2, client_identifier.data, client_identifier.len); data_string_forget(&client_identifier, MDL); @@ -3760,47 +3902,93 @@ isc_result_t client_dns_update (struct client_state *client, int addp, evaluate_option_cache(&client_identifier, NULL, NULL, client, client->sent_options, NULL, &global_scope, oc, MDL)) { - result = get_dhcid(&ddns_dhcid, + result = get_dhcid(&ddns_cb->dhcid, DHO_DHCP_CLIENT_IDENTIFIER, client_identifier.data, client_identifier.len); data_string_forget(&client_identifier, MDL); } else - result = get_dhcid(&ddns_dhcid, 0, + result = get_dhcid(&ddns_cb->dhcid, 0, client->interface->hw_address.hbuf, client->interface->hw_address.hlen); } if (!result) { - data_string_forget(&ddns_fwd_name, MDL); return ISC_R_SUCCESS; } - /* Start the resolver, if necessary. */ - if (!resolver_inited) { - minires_ninit (&resolver_state); - resolver_inited = 1; - resolver_state.retrans = 1; - resolver_state.retry = 1; - } - /* * Perform updates. */ - if (ddns_fwd_name.len && ddns_dhcid.len) { - if (addp) - rcode = ddns_update_fwd(&ddns_fwd_name, *address, - &ddns_dhcid, ttl, 1, 1); - else - rcode = ddns_remove_fwd(&ddns_fwd_name, *address, - &ddns_dhcid); + if (ddns_cb->fwd_name.len && ddns_cb->dhcid.len) { + rcode = ddns_modify_fwd(ddns_cb); } else rcode = ISC_R_FAILURE; - data_string_forget (&ddns_fwd_name, MDL); - data_string_forget (&ddns_dhcid, MDL); + /* + * A success from the modify routine means we are performing + * async processing, for which we use the timedout error message. + */ + if (rcode == ISC_R_SUCCESS) { + rcode = ISC_R_TIMEDOUT; + } + return rcode; } + +/* + * Schedule the first update. They will continue to retry occasionally + * until they no longer time out (or fail). + */ +void +dhclient_schedule_updates(struct client_state *client, + struct iaddr *addr, + int offset) +{ + dhcp_ddns_cb_t *ddns_cb; + struct timeval tv; + + if (!client->config->do_forward_update) + return; + + /* cancel any outstanding ddns requests */ + if (client->ddns_cb != NULL) { + ddns_cancel(client->ddns_cb); + client->ddns_cb = NULL; + } + + ddns_cb = ddns_cb_alloc(MDL); + + if (ddns_cb != NULL) { + ddns_cb->lease = (void *)client; + ddns_cb->address = *addr; + ddns_cb->timeout = 1; + + /* + * XXX: DNS TTL is a problem we need to solve properly. + * Until that time, 300 is a placeholder default for + * something that is less insane than a value scaled + * by lease timeout. + */ + ddns_cb->ttl = 300; + + ddns_cb->state = DDNS_STATE_ADD_FW_NXDOMAIN; + ddns_cb->cur_func = client_dns_update_action; + ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_INCLUDE_RRSET; + + client->ddns_cb = ddns_cb; + + tv.tv_sec = cur_time + offset; + tv.tv_usec = 0; + add_timeout(&tv, client_dns_update_timeout, + ddns_cb, NULL, NULL); + } else { + log_error("Unable to allocate dns update state for %s", + piaddr(*addr)); + } +} +#endif + void dhcpv4_client_assignments(void) { diff --git a/common/Makefile.am b/common/Makefile.am index 8b2f2a97..a771df37 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -3,9 +3,9 @@ AM_CPPFLAGS = -I.. -DLOCALSTATEDIR='"@localstatedir@"' noinst_LIBRARIES = libdhcp.a libdhcp_a_SOURCES = alloc.c bpf.c comapi.c conflex.c ctrace.c discover.c \ dispatch.c dlpi.c dns.c ethernet.c execute.c fddi.c \ - icmp.c inet.c lpf.c memory.c nit.c options.c packet.c \ - parse.c print.c raw.c resolv.c socket.c tables.c tr.c \ - tree.c upf.c heap.c + icmp.c inet.c lpf.c memory.c nit.c ns_name.c options.c \ + packet.c parse.c print.c raw.c resolv.c socket.c \ + tables.c tr.c tree.c upf.c man_MANS = dhcp-eval.5 dhcp-options.5 EXTRA_DIST = $(man_MANS) diff --git a/common/comapi.c b/common/comapi.c index 405c9e65..550156a9 100644 --- a/common/comapi.c +++ b/common/comapi.c @@ -140,7 +140,7 @@ isc_result_t dhcp_group_set_value (omapi_object_t *h, isc_result_t status; if (h -> type != dhcp_type_group) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; group = (struct group_object *)h; /* XXX For now, we can only set these values on new group objects. @@ -159,7 +159,7 @@ isc_result_t dhcp_group_set_value (omapi_object_t *h, value -> u.buffer.len); group -> name [value -> u.buffer.len] = 0; } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return ISC_R_SUCCESS; } @@ -185,19 +185,19 @@ isc_result_t dhcp_group_set_value (omapi_object_t *h, (&group -> group -> statements, parse, &lose, context_any))) { end_parse (&parse); - return ISC_R_BADPARSE; + return DHCP_R_BADPARSE; } end_parse (&parse); return ISC_R_SUCCESS; } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } /* Try to find some inner object that can take the value. */ if (h -> inner && h -> inner -> type -> set_value) { status = ((*(h -> inner -> type -> set_value)) (h -> inner, id, name, value)); - if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED) + if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) return status; } @@ -213,7 +213,7 @@ isc_result_t dhcp_group_get_value (omapi_object_t *h, omapi_object_t *id, isc_result_t status; if (h -> type != dhcp_type_group) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; group = (struct group_object *)h; if (!omapi_ds_strcmp (name, "name")) @@ -235,7 +235,7 @@ isc_result_t dhcp_group_destroy (omapi_object_t *h, const char *file, int line) struct group_object *group, *t; if (h -> type != dhcp_type_group) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; group = (struct group_object *)h; if (group -> name) { @@ -268,14 +268,14 @@ isc_result_t dhcp_group_signal_handler (omapi_object_t *h, int updatep = 0; if (h -> type != dhcp_type_group) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; group = (struct group_object *)h; if (!strcmp (name, "updated")) { /* A group object isn't valid if a subgroup hasn't yet been associated with it. */ if (!group -> group) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* Group objects always have to have names. */ if (!group -> name) { @@ -313,7 +313,7 @@ isc_result_t dhcp_group_stuff_values (omapi_object_t *c, isc_result_t status; if (h -> type != dhcp_type_group) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; group = (struct group_object *)h; /* Write out all the values. */ @@ -345,7 +345,7 @@ isc_result_t dhcp_group_lookup (omapi_object_t **lp, struct group_object *group; if (!ref) - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; /* First see if we were sent a handle. */ status = omapi_get_value_str (ref, id, "handle", &tv); @@ -359,7 +359,7 @@ isc_result_t dhcp_group_lookup (omapi_object_t **lp, /* Don't return the object if the type is wrong. */ if ((*lp) -> type != dhcp_type_group) { omapi_object_dereference (lp, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } } @@ -377,7 +377,7 @@ isc_result_t dhcp_group_lookup (omapi_object_t **lp, if (*lp && *lp != (omapi_object_t *)group) { group_object_dereference (&group, MDL); omapi_object_dereference (lp, MDL); - return ISC_R_KEYCONFLICT; + return DHCP_R_KEYCONFLICT; } else if (!*lp) { /* XXX fix so that hash lookup itself creates XXX the reference. */ @@ -393,7 +393,7 @@ isc_result_t dhcp_group_lookup (omapi_object_t **lp, /* If we get to here without finding a group, no valid key was specified. */ if (!*lp) - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; if (((struct group_object *)(*lp)) -> flags & GROUP_OBJECT_DELETED) { omapi_object_dereference (lp, MDL); @@ -424,7 +424,7 @@ isc_result_t dhcp_group_remove (omapi_object_t *lp, struct group_object *group; isc_result_t status; if (lp -> type != dhcp_type_group) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; group = (struct group_object *)lp; group -> flags |= GROUP_OBJECT_DELETED; @@ -448,7 +448,7 @@ isc_result_t dhcp_control_set_value (omapi_object_t *h, unsigned long newstate; if (h -> type != dhcp_type_control) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; control = (dhcp_control_object_t *)h; if (!omapi_ds_strcmp (name, "state")) { @@ -465,7 +465,7 @@ isc_result_t dhcp_control_set_value (omapi_object_t *h, if (h -> inner && h -> inner -> type -> set_value) { status = ((*(h -> inner -> type -> set_value)) (h -> inner, id, name, value)); - if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED) + if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) return status; } @@ -481,7 +481,7 @@ isc_result_t dhcp_control_get_value (omapi_object_t *h, omapi_object_t *id, isc_result_t status; if (h -> type != dhcp_type_control) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; control = (dhcp_control_object_t *)h; if (!omapi_ds_strcmp (name, "state")) @@ -502,7 +502,7 @@ isc_result_t dhcp_control_destroy (omapi_object_t *h, const char *file, int line) { if (h -> type != dhcp_type_control) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* Can't destroy the control object. */ return ISC_R_NOPERM; @@ -515,7 +515,7 @@ isc_result_t dhcp_control_signal_handler (omapi_object_t *h, isc_result_t status; if (h -> type != dhcp_type_control) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; control = (dhcp_control_object_t *)h; /* Try to find some inner object that can take the value. */ @@ -536,7 +536,7 @@ isc_result_t dhcp_control_stuff_values (omapi_object_t *c, isc_result_t status; if (h -> type != dhcp_type_control) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; control = (dhcp_control_object_t *)h; /* Write out all the values. */ @@ -580,7 +580,7 @@ isc_result_t dhcp_control_lookup (omapi_object_t **lp, /* Don't return the object if the type is wrong. */ if ((*lp) -> type != dhcp_type_control) { omapi_object_dereference (lp, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } } } @@ -616,7 +616,7 @@ isc_result_t dhcp_subnet_set_value (omapi_object_t *h, isc_result_t status; if (h -> type != dhcp_type_subnet) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; subnet = (struct subnet *)h; /* No values to set yet. */ @@ -625,7 +625,7 @@ isc_result_t dhcp_subnet_set_value (omapi_object_t *h, if (h -> inner && h -> inner -> type -> set_value) { status = ((*(h -> inner -> type -> set_value)) (h -> inner, id, name, value)); - if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED) + if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) return status; } @@ -641,7 +641,7 @@ isc_result_t dhcp_subnet_get_value (omapi_object_t *h, omapi_object_t *id, isc_result_t status; if (h -> type != dhcp_type_subnet) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; subnet = (struct subnet *)h; /* No values to get yet. */ @@ -661,7 +661,7 @@ isc_result_t dhcp_subnet_destroy (omapi_object_t *h, const char *file, int line) struct subnet *subnet; if (h -> type != dhcp_type_subnet) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; subnet = (struct subnet *)h; #if defined (DEBUG_MEMORY_LEAKAGE) || \ @@ -690,7 +690,7 @@ isc_result_t dhcp_subnet_signal_handler (omapi_object_t *h, int updatep = 0; if (h -> type != dhcp_type_subnet) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; subnet = (struct subnet *)h; /* Can't write subnets yet. */ @@ -715,7 +715,7 @@ isc_result_t dhcp_subnet_stuff_values (omapi_object_t *c, isc_result_t status; if (h -> type != dhcp_type_subnet) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; subnet = (struct subnet *)h; /* Can't stuff subnet values yet. */ @@ -740,7 +740,7 @@ isc_result_t dhcp_subnet_lookup (omapi_object_t **lp, /* If we get to here without finding a subnet, no valid key was specified. */ if (!*lp) - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; return ISC_R_SUCCESS; } @@ -765,7 +765,7 @@ isc_result_t dhcp_shared_network_set_value (omapi_object_t *h, isc_result_t status; if (h -> type != dhcp_type_shared_network) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; shared_network = (struct shared_network *)h; /* No values to set yet. */ @@ -774,7 +774,7 @@ isc_result_t dhcp_shared_network_set_value (omapi_object_t *h, if (h -> inner && h -> inner -> type -> set_value) { status = ((*(h -> inner -> type -> set_value)) (h -> inner, id, name, value)); - if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED) + if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) return status; } @@ -791,7 +791,7 @@ isc_result_t dhcp_shared_network_get_value (omapi_object_t *h, isc_result_t status; if (h -> type != dhcp_type_shared_network) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; shared_network = (struct shared_network *)h; /* No values to get yet. */ @@ -812,7 +812,7 @@ isc_result_t dhcp_shared_network_destroy (omapi_object_t *h, struct shared_network *shared_network; if (h -> type != dhcp_type_shared_network) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; shared_network = (struct shared_network *)h; #if defined (DEBUG_MEMORY_LEAKAGE) || \ @@ -854,7 +854,7 @@ isc_result_t dhcp_shared_network_signal_handler (omapi_object_t *h, int updatep = 0; if (h -> type != dhcp_type_shared_network) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; shared_network = (struct shared_network *)h; /* Can't write shared_networks yet. */ @@ -879,7 +879,7 @@ isc_result_t dhcp_shared_network_stuff_values (omapi_object_t *c, isc_result_t status; if (h -> type != dhcp_type_shared_network) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; shared_network = (struct shared_network *)h; /* Can't stuff shared_network values yet. */ @@ -904,7 +904,7 @@ isc_result_t dhcp_shared_network_lookup (omapi_object_t **lp, /* If we get to here without finding a shared_network, no valid key was specified. */ if (!*lp) - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; return ISC_R_SUCCESS; } diff --git a/common/conflex.c b/common/conflex.c index 3195bef1..28a456ad 100644 --- a/common/conflex.c +++ b/common/conflex.c @@ -162,7 +162,7 @@ restore_parse_state(struct parse *cfile) { struct parse *saved_state; if (cfile->saved_state == NULL) { - return ISC_R_NOTYET; + return DHCP_R_NOTYET; } saved_state = cfile->saved_state; diff --git a/common/discover.c b/common/discover.c index 7e32b646..23bc9e98 100644 --- a/common/discover.c +++ b/common/discover.c @@ -1247,26 +1247,34 @@ discover_interfaces(int state) { interface_reference (&tmp, next, MDL); } - /* Now register all the remaining interfaces as protocols. */ + /* + * Now register all the remaining interfaces as protocols. + * We register with omapi to allow for control of the interface, + * we've already registered the fd or socket with the socket + * manager as part of if_register_receive(). + */ for (tmp = interfaces; tmp; tmp = tmp -> next) { /* not if it's been registered before */ if (tmp -> flags & INTERFACE_RUNNING) continue; if (tmp -> rfdesc == -1) continue; + switch (local_family) { #ifdef DHCPv6 - if (local_family == AF_INET6) { + case AF_INET6: status = omapi_register_io_object((omapi_object_t *)tmp, if_readsocket, 0, got_one_v6, 0, 0); - } else { -#else - { + break; #endif /* DHCPv6 */ + case AF_INET: + default: status = omapi_register_io_object((omapi_object_t *)tmp, if_readsocket, 0, got_one, 0, 0); + break; } + if (status != ISC_R_SUCCESS) log_fatal ("Can't register I/O handle for %s: %s", tmp -> name, isc_result_totext (status)); @@ -1281,7 +1289,7 @@ discover_interfaces(int state) { if (local_family == AF_INET6) break; #endif - } + } /* for (tmp = interfaces; ... */ if (state == DISCOVER_SERVER && wifcount == 0) { log_info ("%s", ""); @@ -1366,7 +1374,7 @@ isc_result_t got_one (h) struct interface_info *ip; if (h -> type != dhcp_type_interface) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; ip = (struct interface_info *)h; again: @@ -1414,7 +1422,7 @@ got_one_v6(omapi_object_t *h) { unsigned int if_idx = 0; if (h->type != dhcp_type_interface) { - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } ip = (struct interface_info *)h; @@ -1467,7 +1475,7 @@ isc_result_t dhcp_interface_set_value (omapi_object_t *h, isc_result_t status; if (h -> type != dhcp_type_interface) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; interface = (struct interface_info *)h; if (!omapi_ds_strcmp (name, "name")) { @@ -1479,7 +1487,7 @@ isc_result_t dhcp_interface_set_value (omapi_object_t *h, value -> u.buffer.len); interface -> name [value -> u.buffer.len] = 0; } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return ISC_R_SUCCESS; } @@ -1487,7 +1495,7 @@ isc_result_t dhcp_interface_set_value (omapi_object_t *h, if (h -> inner && h -> inner -> type -> set_value) { status = ((*(h -> inner -> type -> set_value)) (h -> inner, id, name, value)); - if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED) + if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) return status; } @@ -1509,7 +1517,7 @@ isc_result_t dhcp_interface_destroy (omapi_object_t *h, struct interface_info *interface; if (h -> type != dhcp_type_interface) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; interface = (struct interface_info *)h; if (interface -> ifp) { @@ -1539,7 +1547,7 @@ isc_result_t dhcp_interface_signal_handler (omapi_object_t *h, isc_result_t status; if (h -> type != dhcp_type_interface) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; interface = (struct interface_info *)h; /* If it's an update signal, see if the interface is dead right @@ -1576,7 +1584,7 @@ isc_result_t dhcp_interface_stuff_values (omapi_object_t *c, isc_result_t status; if (h -> type != dhcp_type_interface) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; interface = (struct interface_info *)h; /* Write out all the values. */ @@ -1611,7 +1619,7 @@ isc_result_t dhcp_interface_lookup (omapi_object_t **ip, struct interface_info *interface; if (!ref) - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; /* First see if we were sent a handle. */ status = omapi_get_value_str (ref, id, "handle", &tv); @@ -1625,7 +1633,7 @@ isc_result_t dhcp_interface_lookup (omapi_object_t **ip, /* Don't return the object if the type is wrong. */ if ((*ip) -> type != dhcp_type_interface) { omapi_object_dereference (ip, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } } @@ -1667,7 +1675,7 @@ isc_result_t dhcp_interface_lookup (omapi_object_t **ip, omapi_value_dereference (&tv, MDL); if (*ip && *ip != (omapi_object_t *)interface) { omapi_object_dereference (ip, MDL); - return ISC_R_KEYCONFLICT; + return DHCP_R_KEYCONFLICT; } else if (!interface) { if (*ip) omapi_object_dereference (ip, MDL); @@ -1681,7 +1689,7 @@ isc_result_t dhcp_interface_lookup (omapi_object_t **ip, /* If we get to here without finding an interface, no valid key was specified. */ if (!*ip) - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; return ISC_R_SUCCESS; } @@ -1748,13 +1756,17 @@ isc_result_t dhcp_interface_remove (omapi_object_t *lp, /* remove the io object */ omapi_unregister_io_object ((omapi_object_t *)interface); - if (local_family == AF_INET) { + switch(local_family) { +#ifdef DHCPv6 + case AF_INET6: + if_deregister6(interface); + break; +#endif /* DHCPv6 */ + case AF_INET: + default: if_deregister_send(interface); if_deregister_receive(interface); -#ifdef DHCPv6 - } else { - if_deregister6(interface); -#endif /* DHCPv6 */ + break; } return ISC_R_SUCCESS; diff --git a/common/dispatch.c b/common/dispatch.c index b97b5c38..ba5fa65b 100644 --- a/common/dispatch.c +++ b/common/dispatch.c @@ -3,7 +3,7 @@ Network input dispatcher... */ /* - * Copyright (c) 2004-2008 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -24,12 +24,6 @@ * * https://www.isc.org/ * - * This software has been written for Internet Systems Consortium - * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. - * To learn more about Internet Systems Consortium, see - * ``https://www.isc.org/''. To learn more about Vixie Enterprises, - * see ``http://www.vix.com''. To learn more about Nominum, Inc., see - * ``http://www.nominum.com''. */ #include "dhcpd.h" @@ -81,20 +75,106 @@ struct timeval *process_outstanding_timeouts (struct timeval *tvp) addressing information from it, and then call through the bootp_packet_handler hook to try to do something with it. */ -void dispatch () +/* + * Use the DHCP timeout list as a place to store DHCP specific + * information, but use the ISC timer system to actually dispatch + * the events. + * + * There are several things that the DHCP timer code does that the + * ISC code doesn't: + * 1) It allows for negative times + * 2) The cancel arguments are different. The DHCP code uses the + * function and data to find the proper timer to cancel while the + * ISC code uses a pointer to the timer. + * 3) The DHCP code includes provision for incrementing and decrementing + * a reference counter associated with the data. + * The first one is fairly easy to fix but will take some time to go throuh + * the callers and update them. The second is also not all that difficult + * in concept - add a pointer to the appropriate structures to hold a pointer + * to the timer and use that. The complications arise in trying to ensure + * that all of the corner cases are covered. The last one is potentially + * more painful and requires more investigation. + * + * The plan is continue with the older DHCP calls and timer list. The + * calls will continue to manipulate the list but will also pass a + * timer to the ISC timer code for the actual dispatch. Later, if desired, + * we can go back and modify the underlying calls to use the ISC + * timer functions directly without requiring all of the code to change + * at the same time. + */ + +void +dispatch(void) { - struct timeval tv, *tvp; isc_result_t status; - /* Wait for a packet or a timeout... XXX */ - do { - tvp = process_outstanding_timeouts (&tv); - status = omapi_one_dispatch (0, tvp); - } while (status == ISC_R_TIMEDOUT || status == ISC_R_SUCCESS); - log_fatal ("omapi_one_dispatch failed: %s -- exiting.", + status = isc_app_ctxrun(dhcp_gbl_ctx.actx); + + isclib_cleanup(); + + log_fatal ("Dispatch routine failed: %s -- exiting", isc_result_totext (status)); } +void +isclib_timer_callback(isc_task_t *taskp, + isc_event_t *eventp) +{ + struct timeout *t = (struct timeout *)eventp->ev_arg; + struct timeout *q, *r; + + /* Get the current time... */ + gettimeofday (&cur_tv, (struct timezone *)0); + + /* + * Find the timeout on the dhcp list and remove it. + * As the list isn't ordered we search the entire list + */ + + r = NULL; + for (q = timeouts; q; q = q->next) { + if (q == t) { + if (r) + r->next = q->next; + else + timeouts = q->next; + break; + } + r = q; + } + + /* + * The timer should always be on the list. If it is we do + * the work and detach the timer block, if not we log an error. + * In both cases we attempt free the ISC event and continue + * processing. + */ + + if (q != NULL) { + /* call the callback function */ + (*(q->func)) (q->what); + if (q->unref) { + (*q->unref) (&q->what, MDL); + } + q->next = free_timeouts; + isc_timer_detach(&q->isc_timeout); + free_timeouts = q; + } else { + /* + * Hmm, we should clean up the timer structure but aren't + * sure about the pointer to the timer block we got so + * don't try to - may change this to a log_fatal + */ + log_error("Error finding timer structure"); + } + + isc_event_free(&eventp); + return; +} + +/* maximum value for usec */ +#define USEC_MAX 1000000 + void add_timeout (when, where, what, ref, unref) struct timeval *when; void (*where) PROTO ((void *)); @@ -103,16 +183,22 @@ void add_timeout (when, where, what, ref, unref) tvunref_t unref; { struct timeout *t, *q; + int usereset = 0; + isc_result_t status; + int sec, usec; + isc_interval_t interval; + isc_time_t expires; /* See if this timeout supersedes an existing timeout. */ t = (struct timeout *)0; - for (q = timeouts; q; q = q -> next) { - if ((where == NULL || q -> func == where) && - q -> what == what) { + for (q = timeouts; q; q = q->next) { + if ((where == NULL || q->func == where) && + q->what == what) { if (t) - t -> next = q -> next; + t->next = q->next; else - timeouts = q -> next; + timeouts = q->next; + usereset = 1; break; } t = q; @@ -123,51 +209,97 @@ void add_timeout (when, where, what, ref, unref) if (!q) { if (free_timeouts) { q = free_timeouts; - free_timeouts = q -> next; + free_timeouts = q->next; } else { q = ((struct timeout *) - dmalloc (sizeof (struct timeout), MDL)); - if (!q) - log_fatal ("add_timeout: no memory!"); + dmalloc(sizeof(struct timeout), MDL)); + if (!q) { + log_fatal("add_timeout: no memory!"); + } } - memset (q, 0, sizeof *q); - q -> func = where; - q -> ref = ref; - q -> unref = unref; - if (q -> ref) - (*q -> ref)(&q -> what, what, MDL); + memset(q, 0, sizeof *q); + q->func = where; + q->ref = ref; + q->unref = unref; + if (q->ref) + (*q->ref)(&q->what, what, MDL); else - q -> what = what; + q->what = what; } - q -> when . tv_sec = when -> tv_sec; - q -> when . tv_usec = when -> tv_usec; + /* We don't really need this, but keep it for now */ + q->when.tv_sec = when->tv_sec; + q->when.tv_usec = when->tv_usec; - /* Now sort this timeout into the timeout list. */ + /* + * Don't bother sorting the DHCP list, just add it to the front. + * Eventually the list should be removed as we migrate the callers + * to the native ISC timer functions, if it becomes a performance + * problem before then we may need to order the list. + */ + q->next = timeouts; + timeouts = q; - /* Beginning of list? */ - if (!timeouts || (timeouts -> when . tv_sec > q -> when . tv_sec) || - ((timeouts -> when . tv_sec == q -> when . tv_sec) && - (timeouts -> when . tv_usec > q -> when . tv_usec))) { - q -> next = timeouts; - timeouts = q; - return; + /* + * Set up the interval values - The previous timers allowed + * negative values to be set, the ISC timer library doesn't like + * that so we make any negative values 0 which sould amount to + * the same thing. + */ + + /* + * The value passed in is a time from an epoch but we need a relative + * time so we need to do some math to try and recover the period. + * This is complicated by the fact that not all of the calls cared + * about the usec value, if it's zero we assume the caller didn't care. + */ + + sec = when->tv_sec - cur_tv.tv_sec; + usec = when->tv_usec - cur_tv.tv_usec; + + if ((when->tv_usec != 0) && (usec < 0)) { + sec--; + usec += USEC_MAX; } - /* Middle of list? */ - for (t = timeouts; t -> next; t = t -> next) { - if ((t -> next -> when . tv_sec > q -> when . tv_sec) || - ((t -> next -> when . tv_sec == q -> when . tv_sec) && - (t -> next -> when . tv_usec > q -> when . tv_usec))) { - q -> next = t -> next; - t -> next = q; - return; - } + if (sec < 0) { + sec = 0; + usec = 0; + } else if (usec < 0) { + usec = 0; + } else if (usec >= USEC_MAX) { + usec = USEC_MAX - 1; } - /* End of list. */ - t -> next = q; - q -> next = (struct timeout *)0; + isc_interval_set(&interval, sec, usec * 1000); + status = isc_time_nowplusinterval(&expires, &interval); + if (status != ISC_R_SUCCESS) { + /* + * The system time function isn't happy or returned + * a value larger than isc_time_t can hold. + */ + log_fatal("Unable to set up timer: %s", + isc_result_totext(status)); + } + + if (usereset == 0) { + status = isc_timer_create(dhcp_gbl_ctx.timermgr, + isc_timertype_once, &expires, + NULL, dhcp_gbl_ctx.task, + isclib_timer_callback, + (void *)q, &q->isc_timeout); + } else { + status = isc_timer_reset(q->isc_timeout, + isc_timertype_once, &expires, + NULL, 0); + } + + /* If it fails log an error and die */ + if (status != ISC_R_SUCCESS) { + log_fatal("Unable to add timeout to isclib\n"); + } + + return; } void cancel_timeout (where, what) @@ -179,21 +311,23 @@ void cancel_timeout (where, what) /* Look for this timeout on the list, and unlink it if we find it. */ t = (struct timeout *)0; for (q = timeouts; q; q = q -> next) { - if (q -> func == where && q -> what == what) { + if (q->func == where && q->what == what) { if (t) - t -> next = q -> next; + t->next = q->next; else - timeouts = q -> next; + timeouts = q->next; break; } t = q; } - /* If we found the timeout, put it on the free list. */ + /* If we found the timeout, cancel it and put it on the free list. */ if (q) { - if (q -> unref) - (*q -> unref) (&q -> what, MDL); - q -> next = free_timeouts; + isc_timer_detach(&q->isc_timeout); + + if (q->unref) + (*q->unref) (&q->what, MDL); + q->next = free_timeouts; free_timeouts = q; } } @@ -203,10 +337,11 @@ void cancel_all_timeouts () { struct timeout *t, *n; for (t = timeouts; t; t = n) { - n = t -> next; - if (t -> unref && t -> what) - (*t -> unref) (&t -> what, MDL); - t -> next = free_timeouts; + n = t->next; + isc_timer_detach(&t->isc_timeout); + if (t->unref && t->what) + (*t->unref) (&t->what, MDL); + t->next = free_timeouts; free_timeouts = t; } } @@ -215,8 +350,8 @@ void relinquish_timeouts () { struct timeout *t, *n; for (t = free_timeouts; t; t = n) { - n = t -> next; - dfree (t, MDL); + n = t->next; + dfree(t, MDL); } } #endif diff --git a/common/dns.c b/common/dns.c index 932de33a..f2da119d 100644 --- a/common/dns.c +++ b/common/dns.c @@ -3,7 +3,7 @@ Domain Name Service subroutines. */ /* - * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2007, 2009 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2001-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -24,25 +24,24 @@ * * https://www.isc.org/ * - * This software has been written for Internet Systems Consortium - * by Ted Lemon in cooperation with Nominum, Inc. - * To learn more about Internet Systems Consortium, see - * ``https://www.isc.org/''. To learn more about Nominum, Inc., see - * ``http://www.nominum.com''. + * The original software was written for Internet Systems Consortium + * by Ted Lemon it has since been extensively modified to use the + * asynchronous DNS routines. */ #include "dhcpd.h" #include "arpa/nameser.h" -#include "dst/md5.h" +#include -/* This file is kind of a crutch for the BIND 8 nsupdate code, which has - * itself been cruelly hacked from its original state. What this code - * does is twofold: first, it maintains a database of zone cuts that can +#include + +/* + * This file contains code to connect the DHCP code to the libdns modules. + * As part of that function it maintains a database of zone cuts that can * be used to figure out which server should be contacted to update any - * given domain name. Secondly, it maintains a set of named TSIG keys, - * and associates those keys with zones. When an update is requested for - * a particular zone, the key associated with that zone is used for the - * update. + * given domain name. Included in the zone information may be a pointer + * to a key in which case that key is used for the update. If no zone + * is found then the DNS code determines the zone on its own. * * The way this works is that you define the domain name to which an * SOA corresponds, and the addresses of some primaries for that domain name: @@ -71,34 +70,31 @@ * "FOO.COM" above, even though theoretically it should try GAZANGA... * and TOPANGA... first. * - * If the update fails with a predefined or cached zone (we'll get to - * those in a second), then it tries to find a more specific zone. This - * is done by looking first for an SOA for GAZANGA.TOPANGA.FOO.COM. Then - * an SOA for TOPANGA.FOO.COM is sought. If during this search a predefined - * or cached zone is found, the update fails - there's something wrong - * somewhere. + * If the update fails with a predefined zone the zone is marked as bad + * and another search of the predefined zones is done. If no predefined + * zone is found finding a zone is left to the DNS module via examination + * of SOA records. If the DNS module finds a zone it may cache the zone + * but the zone won't be cached here. * - * If a more specific zone _is_ found, that zone is cached for the length of - * its TTL in the same database as that described above. TSIG updates are - * never done for cached zones - if you want TSIG updates you _must_ - * write a zone definition linking the key to the zone. In cases where you - * know for sure what the key is but do not want to hardcode the IP addresses - * of the primary or secondaries, a zone declaration can be made that doesn't - * include any primary or secondary declarations. When the DHCP server - * encounters this while hunting up a matching zone for a name, it looks up - * the SOA, fills in the IP addresses, and uses that record for the update. + * TSIG updates are not performed on zones found by the DNS module - if + * you want TSIG updates you _must_ write a zone definition linking the + * key to the zone. In cases where you know for sure what the key is + * but do not want to hardcode the IP addresses of the primary or + * secondaries, a zone declaration can be made that doesn't include any + * primary or secondary declarations. When the DHCP server encounters + * this while hunting up a matching zone for a name, it looks up the SOA, + * fills in the IP addresses, and uses that record for the update. * If the SOA lookup returns NXRRSET, a warning is printed and the zone is - * discarded, TSIG key and all. The search for the zone then continues as if - * the zone record hadn't been found. Zones without IP addresses don't - * match when initially hunting for a predefined or cached zone to update. + * discarded, TSIG key and all. The search for the zone then continues + * as if the zone record hadn't been found. Zones without IP addresses + * don't match when initially hunting for a zone to update. * - * When an update is attempted and no predefined or cached zone is found + * When an update is attempted and no predefined zone is found * that matches any enclosing domain of the domain being updated, the DHCP * server goes through the same process that is done when the update to a - * predefined or cached zone fails - starting with the most specific domain + * predefined zone fails - starting with the most specific domain * name (GAZANGA.TOPANGA.FOO.COM) and moving to the least specific (the root), - * it tries to look up an SOA record. When it finds one, it creates a cached - * zone and attempts an update, and gives up if the update fails. + * it tries to look up an SOA record. * * TSIG keys are defined like this: * @@ -114,11 +110,94 @@ * and the key type must be one of the key types defined in the draft * or by the IANA. Currently only the HMAC-MD5... key type is * supported. + * + * The DDNS processing has been split into two areas. One is the + * control code that determines what should be done. That code is found + * in the client or server directories. The other is the common code + * that performs functions such as properly formatting the arguments. + * That code is found in this file. The basic processing flow for a + * DDNS update is: + * In the client or server code determine what needs to be done and + * collect the necesary information then pass it to a function from + * this file. + * In this code lookup the zone and extract the zone and key information + * (if available) and prepare the arguments for the DNS module. + * When the DNS module completes its work (times out or gets a reply) + * it will trigger another function here which does generic processing + * and then passes control back to the code from the server or client. + * The server or client code then determines the next step which may + * result in another call to this module in which case the process repeats. */ dns_zone_hash_t *dns_zone_hash; +/* + * DHCP dns structures + * Normally the relationship between these structures isn't one to one + * but in the DHCP case it (mostly) is. To make the allocations, frees, + * and passing of the memory easier we make a single structure with all + * the pieces. + * + * The maximum size of the data buffer should be large enough for any + * items DHCP will generate + */ + +typedef struct dhcp_ddns_rdata { + dns_rdata_t rdata; + dns_rdatalist_t rdatalist; + dns_rdataset_t rdataset; +} dhcp_ddns_data_t; + #if defined (NSUPDATE) + +/* + * Code to allocate and free a dddns control block. This block is used + * to pass and track the information associated with a DDNS update request. + */ +dhcp_ddns_cb_t * +ddns_cb_alloc(const char *file, int line) +{ + dhcp_ddns_cb_t *ddns_cb; + int i; + + ddns_cb = dmalloc(sizeof(*ddns_cb), file, line); + if (ddns_cb != NULL) { + ISC_LIST_INIT(ddns_cb->zone_server_list); + for (i = 0; i < DHCP_MAXNS; i++) { + ISC_LINK_INIT(&ddns_cb->zone_addrs[i], link); + } + } + + return(ddns_cb); +} + +void +ddns_cb_free(dhcp_ddns_cb_t *ddns_cb, const char *file, int line) +{ + data_string_forget(&ddns_cb->fwd_name, file, line); + data_string_forget(&ddns_cb->rev_name, file, line); + data_string_forget(&ddns_cb->dhcid, file, line); + + if (ddns_cb->zone != NULL) { + forget_zone((struct dns_zone **)&ddns_cb->zone); + } + + dfree(ddns_cb, file, line); +} + +void +ddns_cb_forget_zone(dhcp_ddns_cb_t *ddns_cb) +{ + int i; + + forget_zone(&ddns_cb->zone); + ddns_cb->zone_name[0] = 0; + ISC_LIST_INIT(ddns_cb->zone_server_list); + for (i = 0; i < DHCP_MAXNS; i++) { + ISC_LINK_INIT(&ddns_cb->zone_addrs[i], link); + } +} + isc_result_t find_tsig_key (ns_tsig_key **key, const char *zname, struct dns_zone *zone) { @@ -128,7 +207,7 @@ isc_result_t find_tsig_key (ns_tsig_key **key, const char *zname, return ISC_R_NOTFOUND; if (!zone -> key) { - return ISC_R_KEY_UNKNOWN; + return DHCP_R_KEY_UNKNOWN; } if ((!zone -> key -> name || @@ -138,7 +217,7 @@ isc_result_t find_tsig_key (ns_tsig_key **key, const char *zname, (!zone -> key) || (!zone -> key -> key) || (zone -> key -> key -> len == 0)) { - return ISC_R_INVALIDKEY; + return DHCP_R_INVALIDKEY; } tkey = dmalloc (sizeof *tkey, MDL); if (!tkey) { @@ -189,6 +268,7 @@ isc_result_t enter_dns_zone (struct dns_zone *zone) if (!dns_zone_new_hash(&dns_zone_hash, DNS_HASH_SIZE, MDL)) return ISC_R_NOMEMORY; } + dns_zone_hash_add (dns_zone_hash, zone -> name, 0, zone, MDL); return ISC_R_SUCCESS; } @@ -270,30 +350,32 @@ int dns_zone_dereference (ptr, file, line) } #if defined (NSUPDATE) -isc_result_t find_cached_zone (const char *dname, ns_class class, - char *zname, size_t zsize, - struct in_addr *addrs, - int naddrs, int *naddrout, - struct dns_zone **zcookie) +isc_result_t +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 data_string nsaddrs; + struct in_addr zone_addr; int ix; - /* The absence of the zcookie pointer indicates that we - succeeded previously, but the update itself failed, meaning - that we shouldn't use the cached zone. */ - if (!zcookie) - return ISC_R_NOTFOUND; + if (direction == FIND_FORWARD) { + np = (const char *)ddns_cb->fwd_name.data; + } else { + np = (const char *)ddns_cb->rev_name.data; + } /* We can't look up a null zone. */ - if (!dname || !*dname) - return ISC_R_INVALIDARG; + if ((np == NULL) || (*np == '\0')) { + return DHCP_R_INVALIDARG; + } - /* For each subzone, try to find a cached zone. */ - for (np = dname; np; np = strchr (np, '.')) { + /* + * For each subzone, try to find a cached zone. + * Skip the first zone as that shouldn't work. + */ + for (np = strchr(np, '.'); np != NULL; np = strchr(np, '.')) { np++; status = dns_zone_lookup (&zone, np); if (status == ISC_R_SUCCESS) @@ -310,11 +392,11 @@ isc_result_t find_cached_zone (const char *dname, ns_class class, } /* Make sure the zone name will fit. */ - if (strlen (zone -> name) > zsize) { + if (strlen(zone->name) > sizeof(ddns_cb->zone_name)) { dns_zone_dereference (&zone, MDL); return ISC_R_NOSPACE; } - strcpy (zname, zone -> name); + strcpy((char *)&ddns_cb->zone_name[0], zone->name); memset (&nsaddrs, 0, sizeof nsaddrs); ix = 0; @@ -328,10 +410,16 @@ isc_result_t find_cached_zone (const char *dname, ns_class class, &global_scope, zone -> primary, MDL)) { int ip = 0; - while (ix < naddrs) { + while (ix < DHCP_MAXNS) { if (ip + 4 > nsaddrs.len) break; - memcpy (&addrs [ix], &nsaddrs.data [ip], 4); + memcpy(&zone_addr, &nsaddrs.data[ip], 4); + isc_sockaddr_fromin(&ddns_cb->zone_addrs[ix], + &zone_addr, + NS_DEFAULTPORT); + ISC_LIST_APPEND(ddns_cb->zone_server_list, + &ddns_cb->zone_addrs[ix], + link); ip += 4; ix++; } @@ -347,10 +435,16 @@ isc_result_t find_cached_zone (const char *dname, ns_class class, &global_scope, zone -> secondary, MDL)) { int ip = 0; - while (ix < naddrs) { + while (ix < DHCP_MAXNS) { if (ip + 4 > nsaddrs.len) break; - memcpy (&addrs [ix], &nsaddrs.data [ip], 4); + memcpy(&zone_addr, &nsaddrs.data[ip], 4); + isc_sockaddr_fromin(&ddns_cb->zone_addrs[ix], + &zone_addr, + NS_DEFAULTPORT); + ISC_LIST_APPEND(ddns_cb->zone_server_list, + &ddns_cb->zone_addrs[ix], + link); ip += 4; ix++; } @@ -358,14 +452,8 @@ isc_result_t find_cached_zone (const char *dname, ns_class class, } } - /* It's not an error for zcookie to have a value here - actually, - it's quite likely, because res_nupdate cycles through all the - names in the update looking for their zones. */ - if (!*zcookie) - dns_zone_reference (zcookie, zone, MDL); + dns_zone_reference(&ddns_cb->zone, zone, MDL); dns_zone_dereference (&zone, MDL); - if (naddrout) - *naddrout = ix; return ISC_R_SUCCESS; } @@ -386,82 +474,26 @@ void repudiate_zone (struct dns_zone **zone) dns_zone_dereference (zone, MDL); } -void cache_found_zone (ns_class class, - char *zname, struct in_addr *addrs, int naddrs) -{ - struct dns_zone *zone = (struct dns_zone *)0; - int ix = strlen (zname); - - if (zname [ix - 1] == '.') - ix = 0; - - /* See if there's already such a zone. */ - if (dns_zone_lookup (&zone, zname) == ISC_R_SUCCESS) { - /* If it's not a dynamic zone, leave it alone. */ - if (!zone -> timeout) - return; - /* Address may have changed, so just blow it away. */ - if (zone -> primary) - option_cache_dereference (&zone -> primary, MDL); - if (zone -> secondary) - option_cache_dereference (&zone -> secondary, MDL); - } else if (!dns_zone_allocate (&zone, MDL)) - return; - - if (!zone -> name) { - zone -> name = - dmalloc (strlen (zname) + 1 + (ix != 0), MDL); - if (!zone -> name) { - dns_zone_dereference (&zone, MDL); - return; - } - strcpy (zone -> name, zname); - /* Add a trailing '.' if it was missing. */ - if (ix) { - zone -> name [ix] = '.'; - zone -> name [ix + 1] = 0; - } - } - - /* XXX Need to get the lower-level code to push the actual zone - XXX TTL up to us. */ - zone -> timeout = cur_time + 1800; - - if (!option_cache_allocate (&zone -> primary, MDL)) { - dns_zone_dereference (&zone, MDL); - return; - } - if (!buffer_allocate (&zone -> primary -> data.buffer, - naddrs * sizeof (struct in_addr), MDL)) { - dns_zone_dereference (&zone, MDL); - return; - } - memcpy (zone -> primary -> data.buffer -> data, - addrs, naddrs * sizeof *addrs); - zone -> primary -> data.data = - &zone -> primary -> data.buffer -> data [0]; - zone -> primary -> data.len = naddrs * sizeof *addrs; - - enter_dns_zone (zone); -} - /* Have to use TXT records for now. */ #define T_DHCID T_TXT int get_dhcid (struct data_string *id, int type, const u_int8_t *data, unsigned len) { - unsigned char buf[MD5_DIGEST_LENGTH]; - MD5_CTX md5; + unsigned char buf[ISC_MD5_DIGESTLENGTH]; + isc_md5_t md5; int i; /* Types can only be 0..(2^16)-1. */ if (type < 0 || type > 65535) return 0; - /* Hexadecimal MD5 digest plus two byte type and NUL. */ + /* + * Hexadecimal MD5 digest plus two byte type, NUL, + * and one byte for length for dns. + */ if (!buffer_allocate (&id -> buffer, - (MD5_DIGEST_LENGTH * 2) + 3, MDL)) + (ISC_MD5_DIGESTLENGTH * 2) + 4, MDL)) return 0; id -> data = id -> buffer -> data; @@ -480,556 +512,867 @@ int get_dhcid (struct data_string *id, * -- "Interaction between DHCP and DNS" * * M. Stapp, Y. Rekhter + * + * We put the length into the first byte to turn + * this into a dns text string. This avoid needing to + * copy the string to add the byte later. */ + id->buffer->data[0] = ISC_MD5_DIGESTLENGTH * 2 + 2; - /* Put the type in the first two bytes. */ - id -> buffer -> data [0] = "0123456789abcdef" [type >> 4]; - id -> buffer -> data [1] = "0123456789abcdef" [type % 15]; - + /* Put the type in the next two bytes. */ + id->buffer->data[1] = "0123456789abcdef"[type >> 4]; + id->buffer->data[2] = "0123456789abcdef"[type % 15]; + /* Mash together an MD5 hash of the identifier. */ - MD5_Init (&md5); - MD5_Update (&md5, data, len); - MD5_Final (buf, &md5); + isc_md5_init(&md5); + isc_md5_update(&md5, data, len); + isc_md5_final(&md5, buf); /* Convert into ASCII. */ - for (i = 0; i < MD5_DIGEST_LENGTH; i++) { - id -> buffer -> data [i * 2 + 2] = - "0123456789abcdef" [(buf [i] >> 4) & 0xf]; - id -> buffer -> data [i * 2 + 3] = - "0123456789abcdef" [buf [i] & 0xf]; + for (i = 0; i < ISC_MD5_DIGESTLENGTH; i++) { + id->buffer->data[i * 2 + 3] = + "0123456789abcdef"[(buf[i] >> 4) & 0xf]; + id->buffer->data[i * 2 + 4] = + "0123456789abcdef"[buf[i] & 0xf]; } - id -> len = MD5_DIGEST_LENGTH * 2 + 2; - id -> buffer -> data [id -> len] = 0; - id -> terminated = 1; + + id->len = ISC_MD5_DIGESTLENGTH * 2 + 3; + id->buffer->data[id->len] = 0; + id->terminated = 1; return 1; } -/* Now for the DDNS update code that is shared between client and - server... */ +/* + * The dhcid (text version) that we pass to DNS includes a length byte + * at the start but the text we store in the lease doesn't include the + * length byte. The following routines are to convert between the two + * styles. + * + * When converting from a dhcid to a leaseid we reuse the buffer and + * simply adjust the data pointer and length fields in the data string. + * This avoids any prolems with allocating space. + */ + +void +dhcid_tolease(struct data_string *dhcid, + struct data_string *leaseid) +{ + /* copy the data string then update the fields */ + data_string_copy(leaseid, dhcid, MDL); + leaseid->data++; + leaseid->len--; +} isc_result_t -ddns_update_fwd(struct data_string *ddns_fwd_name, struct iaddr ddns_addr, - struct data_string *ddns_dhcid, unsigned long ttl, - unsigned rrsetp, unsigned conflict) { - ns_updque updqueue; - ns_updrec *updrec; +dhcid_fromlease(struct data_string *dhcid, + struct data_string *leaseid) +{ + if (!buffer_allocate(&dhcid->buffer, leaseid->len + 2, MDL)) { + return(ISC_R_FAILURE); + } + + dhcid->data = dhcid->buffer->data; + + dhcid->buffer->data[0] = leaseid->len; + memcpy(dhcid->buffer->data + 1, leaseid->data, leaseid->len); + dhcid->len = leaseid->len + 1; + if (leaseid->terminated == 1) { + dhcid->buffer->data[dhcid->len] = 0; + dhcid->terminated = 1; + } + + return(ISC_R_SUCCESS); +} + +/* + * Construct the dataset for this item. + * This is a fairly simple arrangement as the operations we do are simple. + * If there is data we simply have the rdata point to it - the formatting + * must be correct already. We then link the rdatalist to the rdata and + * create a rdataset from the rdatalist. + */ + +static isc_result_t +make_dns_dataset(dns_rdataclass_t dataclass, + dns_rdatatype_t datatype, + dhcp_ddns_data_t *dataspace, + unsigned char *data, + int datalen, + int ttl) +{ + dns_rdata_t *rdata = &dataspace->rdata; + dns_rdatalist_t *rdatalist = &dataspace->rdatalist;; + dns_rdataset_t *rdataset = &dataspace->rdataset; + + isc_region_t region; + + /* set up the rdata */ + dns_rdata_init(rdata); + + if (data == NULL) { + /* No data, set up the rdata fields we care about */ + rdata->flags = DNS_RDATA_UPDATE; + rdata->type = datatype; + rdata->rdclass = dataclass; + } else { + switch(datatype) { + case dns_rdatatype_a: + case dns_rdatatype_aaaa: + case dns_rdatatype_txt: + case dns_rdatatype_dhcid: + case dns_rdatatype_ptr: + /* The data must be in the right format we simply + * need to supply it via the correct structure */ + region.base = data; + region.length = datalen; + dns_rdata_fromregion(rdata, dataclass, datatype, + ®ion); + break; + default: + return(DHCP_R_INVALIDARG); + break; + } + } + + /* setup the datalist and attach the rdata to it */ + dns_rdatalist_init(rdatalist); + rdatalist->type = datatype; + rdatalist->rdclass = dataclass; + rdatalist->ttl = ttl; + ISC_LIST_APPEND(rdatalist->rdata, rdata, link); + + /* convert the datalist to a dataset */ + dns_rdataset_init(rdataset); + dns_rdatalist_tordataset(rdatalist, rdataset); + + return(ISC_R_SUCCESS); +} + +/* + * When a DHCP client or server intends to update an A RR, it first + * prepares a DNS UPDATE query which includes as a prerequisite the + * assertion that the name does not exist. The update section of the + * query attempts to add the new name and its IP address mapping (an A + * RR), and the DHCID RR with its unique client-identity. + * -- "Interaction between DHCP and DNS" + * + * There are two cases, one for the server and one for the client. + * + * For the server the first step will have a request of: + * The name is not in use + * Add an A RR + * Add a DHCID RR (currently txt) + * + * For the client the first step will have a request of: + * The A RR does not exist + * Add an A RR + * Add a DHCID RR (currently txt) + */ + +static isc_result_t +ddns_modify_fwd_add1(dhcp_ddns_cb_t *ddns_cb, + dhcp_ddns_data_t *dataspace, + dns_name_t *pname, + dns_name_t *uname) +{ isc_result_t result; - const char *logstr; - char ddns_address[ - sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; - int ddns_address_type; - /* - * We want to delete either A or AAAA records, depending on - * whether we have an IPv4 or an IPv6 address. - */ - if (ddns_addr.len == 4) { - ddns_address_type = T_A; - } else if (ddns_addr.len == 16) { - ddns_address_type = T_AAAA; + /* Construct the prerequisite list */ + if ((ddns_cb->flags & DDNS_INCLUDE_RRSET) != 0) { + /* The A RR shouldn't exist */ + result = make_dns_dataset(dns_rdataclass_none, + ddns_cb->address_type, + dataspace, NULL, 0, 0); } else { - return ISC_R_INVALIDARG; + /* The name is not in use */ + result = make_dns_dataset(dns_rdataclass_none, + dns_rdatatype_any, + dataspace, NULL, 0, 0); } - strcpy(ddns_address, piaddr(ddns_addr)); - - /* - * When a DHCP client or server intends to update an A RR, it first - * prepares a DNS UPDATE query which includes as a prerequisite the - * assertion that the name does not exist. The update section of the - * query attempts to add the new name and its IP address mapping (an A - * RR), and the DHCID RR with its unique client-identity. - * -- "Interaction between DHCP and DNS" - */ - - ISC_LIST_INIT (updqueue); - - /* - * A RR does not exist. - */ - updrec = minires_mkupdrec (S_PREREQ, - (const char *)ddns_fwd_name -> data, - C_IN, ddns_address_type, 0); - if (!updrec) { - result = ISC_R_NOMEMORY; - goto error; + if (result != ISC_R_SUCCESS) { + return(result); } + ISC_LIST_APPEND(pname->list, &dataspace->rdataset, link); + dataspace++; - updrec -> r_data = (unsigned char *)0; - updrec -> r_size = 0; - updrec -> r_opcode = rrsetp ? NXRRSET : NXDOMAIN; - - ISC_LIST_APPEND (updqueue, updrec, r_link); - - - /* - * Add A RR. - */ - updrec = minires_mkupdrec (S_UPDATE, - (const char *)ddns_fwd_name -> data, - C_IN, ddns_address_type, ttl); - if (!updrec) { - result = ISC_R_NOMEMORY; - goto error; + /* Construct the update list */ + /* Add the A RR */ + result = make_dns_dataset(dns_rdataclass_in, ddns_cb->address_type, + dataspace, + (unsigned char *)ddns_cb->address.iabuf, + ddns_cb->address.len, ddns_cb->ttl); + if (result != ISC_R_SUCCESS) { + return(result); } + ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link); + dataspace++; - updrec -> r_data = (unsigned char *)ddns_address; - updrec -> r_size = strlen (ddns_address); - updrec -> r_opcode = ADD; - - ISC_LIST_APPEND (updqueue, updrec, r_link); - - - /* - * Add DHCID RR. - */ - updrec = minires_mkupdrec (S_UPDATE, - (const char *)ddns_fwd_name -> data, - C_IN, T_DHCID, ttl); - if (!updrec) { - result = ISC_R_NOMEMORY; - goto error; + /* Add the DHCID RR */ + result = make_dns_dataset(dns_rdataclass_in, dns_rdatatype_txt, + dataspace, + (unsigned char *)ddns_cb->dhcid.data, + ddns_cb->dhcid.len, ddns_cb->ttl); + if (result != ISC_R_SUCCESS) { + return(result); } + ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link); - updrec -> r_data = ddns_dhcid -> data; - updrec -> r_size = ddns_dhcid -> len; - updrec -> r_opcode = ADD; - - ISC_LIST_APPEND (updqueue, updrec, r_link); - - - /* - * Attempt to perform the update. - */ - result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue)); - -#ifdef DEBUG_DNS_UPDATES - print_dns_status ((int)result, &updqueue); -#endif - - /* - * If this update operation succeeds, the updater can conclude that it - * has added a new name whose only RRs are the A and DHCID RR records. - * The A RR update is now complete (and a client updater is finished, - * while a server might proceed to perform a PTR RR update). - * -- "Interaction between DHCP and DNS" - */ - - if (result == ISC_R_SUCCESS) { - log_info ("Added new forward map from %.*s to %s", - (int)ddns_fwd_name -> len, - (const char *)ddns_fwd_name -> data, ddns_address); - goto error; - } - - - /* - * If the first update operation fails with YXDOMAIN, the updater can - * conclude that the intended name is in use. The updater then - * attempts to confirm that the DNS name is not being used by some - * other host. The updater prepares a second UPDATE query in which the - * prerequisite is that the desired name has attached to it a DHCID RR - * whose contents match the client identity. The update section of - * this query deletes the existing A records on the name, and adds the - * A record that matches the DHCP binding and the DHCID RR with the - * client identity. - * -- "Interaction between DHCP and DNS" - */ - - if (result != (rrsetp ? ISC_R_YXRRSET : ISC_R_YXDOMAIN)) { - log_error ("Unable to add forward map from %.*s to %s: %s", - (int)ddns_fwd_name -> len, - (const char *)ddns_fwd_name -> data, ddns_address, - isc_result_totext (result)); - goto error; - } - - while (!ISC_LIST_EMPTY (updqueue)) { - updrec = ISC_LIST_HEAD (updqueue); - ISC_LIST_UNLINK (updqueue, updrec, r_link); - minires_freeupdrec (updrec); - } - - /* If we're doing conflict resolution, we use a set of prereqs. If - * not, we delete the DHCID in addition to all A rrsets. - */ - if (conflict) { - /* - * DHCID RR exists, and matches client identity. - */ - updrec = minires_mkupdrec (S_PREREQ, - (const char *)ddns_fwd_name -> data, - C_IN, T_DHCID, 0); - if (!updrec) { - result = ISC_R_NOMEMORY; - goto error; - } - - updrec -> r_data = ddns_dhcid -> data; - updrec -> r_size = ddns_dhcid -> len; - updrec -> r_opcode = YXRRSET; - - ISC_LIST_APPEND (updqueue, updrec, r_link); - } else { - /* - * Conflict detection override: delete DHCID RRs. - */ - updrec = minires_mkupdrec(S_UPDATE, - (const char *)ddns_fwd_name->data, - C_IN, T_DHCID, 0); - - if (!updrec) { - result = ISC_R_NOMEMORY; - goto error; - } - - updrec->r_data = NULL; - updrec->r_size = 0; - updrec->r_opcode = DELETE; - - ISC_LIST_APPEND(updqueue, updrec, r_link); - - - /* - * With all other DHCID RR's deleted, add this client's - * DHCID unconditionally (as update-conflict-detection is - * disabled). - */ - updrec = minires_mkupdrec(S_UPDATE, - (const char *)ddns_fwd_name->data, - C_IN, T_DHCID, ttl); - if (!updrec) { - result = ISC_R_NOMEMORY; - goto error; - } - - updrec->r_data = ddns_dhcid->data; - updrec->r_size = ddns_dhcid->len; - updrec->r_opcode = ADD; - - ISC_LIST_APPEND (updqueue, updrec, r_link); - } - - - /* - * Delete A RRset. - */ - updrec = minires_mkupdrec (S_UPDATE, - (const char *)ddns_fwd_name -> data, - C_IN, ddns_address_type, 0); - if (!updrec) { - result = ISC_R_NOMEMORY; - goto error; - } - - updrec -> r_data = (unsigned char *)0; - updrec -> r_size = 0; - updrec -> r_opcode = DELETE; - - ISC_LIST_APPEND (updqueue, updrec, r_link); - - - /* - * Add A RR. - */ - updrec = minires_mkupdrec (S_UPDATE, - (const char *)ddns_fwd_name -> data, - C_IN, ddns_address_type, ttl); - if (!updrec) { - result = ISC_R_NOMEMORY; - goto error; - } - - updrec -> r_data = (unsigned char *)ddns_address; - updrec -> r_size = strlen (ddns_address); - updrec -> r_opcode = ADD; - - ISC_LIST_APPEND (updqueue, updrec, r_link); - - - /* - * Attempt to perform the update. - */ - result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue)); - - switch (result) { - case ISC_R_SUCCESS: - logstr = NULL; - break; - - case ISC_R_YXRRSET: - case ISC_R_YXDOMAIN: - logstr = "DHCID mismatch, belongs to another client."; - break; - - case ISC_R_NXRRSET: - case ISC_R_NXDOMAIN: - logstr = "Has an address record but no DHCID, not mine."; - break; - - default: - logstr = isc_result_totext(result); - break; - } - - if (logstr != NULL) - log_error("Forward map from %.*s to %s FAILED: %s", - (int)ddns_fwd_name -> len, - (const char *)ddns_fwd_name -> data, - ddns_address, logstr); - else - log_info("Added new forward map from %.*s to %s", - (int)ddns_fwd_name -> len, - (const char *)ddns_fwd_name -> data, ddns_address); - -#if defined (DEBUG_DNS_UPDATES) - print_dns_status ((int)result, &updqueue); -#endif - - /* - * If this query succeeds, the updater can conclude that the current - * client was the last client associated with the domain name, and that - * the name now contains the updated A RR. The A RR update is now - * complete (and a client updater is finished, while a server would - * then proceed to perform a PTR RR update). - * -- "Interaction between DHCP and DNS" - */ - - /* - * If the second query fails with NXRRSET, the updater must conclude - * that the client's desired name is in use by another host. At this - * juncture, the updater can decide (based on some administrative - * configuration outside of the scope of this document) whether to let - * the existing owner of the name keep that name, and to (possibly) - * perform some name disambiguation operation on behalf of the current - * client, or to replace the RRs on the name with RRs that represent - * the current client. If the configured policy allows replacement of - * existing records, the updater submits a query that deletes the - * existing A RR and the existing DHCID RR, adding A and DHCID RRs that - * represent the IP address and client-identity of the new client. - * -- "Interaction between DHCP and DNS" - */ - - error: - while (!ISC_LIST_EMPTY (updqueue)) { - updrec = ISC_LIST_HEAD (updqueue); - ISC_LIST_UNLINK (updqueue, updrec, r_link); - minires_freeupdrec (updrec); - } - - return result; + return(ISC_R_SUCCESS); } +/* + * If the first update operation fails with YXDOMAIN, the updater can + * conclude that the intended name is in use. The updater then + * attempts to confirm that the DNS name is not being used by some + * other host. The updater prepares a second UPDATE query in which the + * prerequisite is that the desired name has attached to it a DHCID RR + * whose contents match the client identity. The update section of + * this query deletes the existing A records on the name, and adds the + * A record that matches the DHCP binding and the DHCID RR with the + * client identity. + * -- "Interaction between DHCP and DNS" + * + * The message for the second step depends on if we are doing conflict + * resolution. If we are we include a prerequisite. If not we delete + * the DHCID in addition to all A rrsets. + * + * Conflict resolution: + * DHCID RR exists, and matches client identity. + * Delete A RRset. + * Add A RR. + * + * Conflict override: + * Delete DHCID RRs. + * Add DHCID RR + * Delete A RRset. + * Add A RR. + */ + +static isc_result_t +ddns_modify_fwd_add2(dhcp_ddns_cb_t *ddns_cb, + dhcp_ddns_data_t *dataspace, + dns_name_t *pname, + dns_name_t *uname) +{ + isc_result_t result; + + /* + * If we are doing conflict resolution (unset) we use a prereq list. + * If not we delete the DHCID in addition to all A rrsets. + */ + if ((ddns_cb->flags & DDNS_CONFLICT_OVERRIDE) == 0) { + /* Construct the prereq list */ + /* The DHCID RR exists and matches the client identity */ + result = make_dns_dataset(dns_rdataclass_in, dns_rdatatype_txt, + dataspace, + (unsigned char *)ddns_cb->dhcid.data, + ddns_cb->dhcid.len, 0); + if (result != ISC_R_SUCCESS) { + return(result); + } + ISC_LIST_APPEND(pname->list, &dataspace->rdataset, link); + dataspace++; + } else { + /* Start constructing the update list. + * Conflict detection override: delete DHCID RRs */ + result = make_dns_dataset(dns_rdataclass_any, + dns_rdatatype_txt, + dataspace, NULL, 0, 0); + if (result != ISC_R_SUCCESS) { + return(result); + } + ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link); + dataspace++; + + /* Add current DHCID RR */ + result = make_dns_dataset(dns_rdataclass_in, dns_rdatatype_txt, + dataspace, + (unsigned char *)ddns_cb->dhcid.data, + ddns_cb->dhcid.len, ddns_cb->ttl); + if (result != ISC_R_SUCCESS) { + return(result); + } + ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link); + dataspace++; + } + + /* Start or continue constructing the update list */ + /* Delete the A RRset */ + result = make_dns_dataset(dns_rdataclass_any, ddns_cb->address_type, + dataspace, NULL, 0, 0); + if (result != ISC_R_SUCCESS) { + return(result); + } + ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link); + dataspace++; + + /* Add the A RR */ + result = make_dns_dataset(dns_rdataclass_in, ddns_cb->address_type, + dataspace, + (unsigned char *)ddns_cb->address.iabuf, + ddns_cb->address.len, ddns_cb->ttl); + if (result != ISC_R_SUCCESS) { + return(result); + } + ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link); + + return(ISC_R_SUCCESS); +} + +/* + * The entity chosen to handle the A record for this client (either the + * client or the server) SHOULD delete the A record that was added when + * the lease was made to the client. + * + * In order to perform this delete, the updater prepares an UPDATE + * query which contains two prerequisites. The first prerequisite + * asserts that the DHCID RR exists whose data is the client identity + * described in Section 4.3. The second prerequisite asserts that the + * data in the A RR contains the IP address of the lease that has + * expired or been released. + * -- "Interaction between DHCP and DNS" + * + * First try has: + * DHCID RR exists, and matches client identity. + * A RR matches the expiring lease. + * Delete appropriate A RR. + */ + +static isc_result_t +ddns_modify_fwd_rem1(dhcp_ddns_cb_t *ddns_cb, + dhcp_ddns_data_t *dataspace, + dns_name_t *pname, + dns_name_t *uname) +{ + isc_result_t result; + + /* Consruct the prereq list */ + /* The DHCID RR exists and matches the client identity */ + result = make_dns_dataset(dns_rdataclass_in, dns_rdatatype_txt, + dataspace, + (unsigned char *)ddns_cb->dhcid.data, + ddns_cb->dhcid.len, 0); + if (result != ISC_R_SUCCESS) { + return(result); + } + ISC_LIST_APPEND(pname->list, &dataspace->rdataset, link); + dataspace++; + + /* The A RR matches the expiring lease */ + result = make_dns_dataset(dns_rdataclass_in, ddns_cb->address_type, + dataspace, + (unsigned char *)ddns_cb->address.iabuf, + ddns_cb->address.len, 0); + if (result != ISC_R_SUCCESS) { + return(result); + } + ISC_LIST_APPEND(pname->list, &dataspace->rdataset, link); + dataspace++; + + /* Construct the update list */ + /* Delete A RRset */ + result = make_dns_dataset(dns_rdataclass_none, ddns_cb->address_type, + dataspace, + (unsigned char *)ddns_cb->address.iabuf, + ddns_cb->address.len, 0); + if (result != ISC_R_SUCCESS) { + return(result); + } + ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link); + + return(ISC_R_SUCCESS); +} + +/* + * If the deletion of the A succeeded, and there are no A or AAAA + * records left for this domain, then we can blow away the DHCID + * record as well. We can't blow away the DHCID record above + * because it's possible that more than one record has been added + * to this domain name. + * + * Second query has: + * A RR does not exist. + * AAAA RR does not exist. + * Delete appropriate DHCID RR. + */ + +static isc_result_t +ddns_modify_fwd_rem2(dhcp_ddns_cb_t *ddns_cb, + dhcp_ddns_data_t *dataspace, + dns_name_t *pname, + dns_name_t *uname) +{ + isc_result_t result; + + /* Construct the prereq list */ + /* The A RR does not exist */ + result = make_dns_dataset(dns_rdataclass_none, dns_rdatatype_a, + dataspace, NULL, 0, 0); + if (result != ISC_R_SUCCESS) { + return(result); + } + ISC_LIST_APPEND(pname->list, &dataspace->rdataset, link); + dataspace++; + + /* The AAAA RR does not exist */ + result = make_dns_dataset(dns_rdataclass_none, dns_rdatatype_aaaa, + dataspace, NULL, 0, 0); + if (result != ISC_R_SUCCESS) { + return(result); + } + ISC_LIST_APPEND(pname->list, &dataspace->rdataset, link); + dataspace++; + + /* Construct the update list */ + /* Delete DHCID RR */ + result = make_dns_dataset(dns_rdataclass_none, dns_rdatatype_txt, + dataspace, + (unsigned char *)ddns_cb->dhcid.data, + ddns_cb->dhcid.len, 0); + if (result != ISC_R_SUCCESS) { + return(result); + } + ISC_LIST_APPEND(uname->list, &dataspace->rdataset, link); + + return(ISC_R_SUCCESS); +} + +/* + * This routine converts from the task action call into something + * easier to work with. It also handles the common case of a signature + * or zone not being correct. + */ +void ddns_interlude(isc_task_t *taskp, + isc_event_t *eventp) +{ + dhcp_ddns_cb_t *ddns_cb = (dhcp_ddns_cb_t *)eventp->ev_arg; + dns_clientupdateevent_t *ddns_event = (dns_clientupdateevent_t *)eventp; + isc_result_t eresult = ddns_event->result; + isc_result_t result; + + /* We've extracted the information we want from it, get rid of + * the event block.*/ + isc_event_free(&eventp); + + /* This transaction is complete, clear the value */ + ddns_cb->transaction = NULL; + + /* If we cancelled or tried to cancel the operation we just + * need to clean up. */ + if ((eresult == ISC_R_CANCELED) || + ((ddns_cb->flags & DDNS_ABORT) != 0)) { + if (ddns_cb->next_op != NULL) { + /* if necessary cleanup up next op block */ + ddns_cb_free(ddns_cb->next_op, MDL); + } + ddns_cb_free(ddns_cb, MDL); + return; + } + + /* If we had a problem with our key or zone try again */ + if ((eresult == DNS_R_NOTAUTH) || + (eresult == DNS_R_NOTZONE)) { + int i; + /* Our zone information was questionable, + * repudiate it and try again */ + repudiate_zone(&ddns_cb->zone); + ddns_cb->zone_name[0] = 0; + ISC_LIST_INIT(ddns_cb->zone_server_list); + for (i = 0; i < DHCP_MAXNS; i++) { + ISC_LINK_INIT(&ddns_cb->zone_addrs[i], link); + } + + if ((ddns_cb->state & + (DDNS_STATE_ADD_PTR | DDNS_STATE_REM_PTR)) != 0) { + result = ddns_modify_ptr(ddns_cb); + } else { + result = ddns_modify_fwd(ddns_cb); + } + + if (result != ISC_R_SUCCESS) { + /* if we couldn't redo the query toss it */ + if (ddns_cb->next_op != NULL) { + /* cleanup up next op block */ + ddns_cb_free(ddns_cb->next_op, MDL); + } + ddns_cb_free(ddns_cb, MDL); + } + return; + } else { + /* pass it along to be processed */ + ddns_cb->cur_func(ddns_cb, eresult); + } + + return; +} + +/* + * This routine does the generic work for sending a ddns message to + * modify the forward record (A or AAAA) and calls one of a set of + * routines to build the specific message. + */ + isc_result_t -ddns_remove_fwd(struct data_string *ddns_fwd_name, - struct iaddr ddns_addr, - struct data_string *ddns_dhcid) { - ns_updque updqueue; - ns_updrec *updrec; - isc_result_t result = SERVFAIL; - char ddns_address[ - sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; - int ddns_address_type; +ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb) +{ + isc_result_t result; + dns_tsec_t *tsec_key = NULL; - /* - * We want to delete either A or AAAA records, depending on - * whether we have an IPv4 or an IPv6 address. - */ - if (ddns_addr.len == 4) { - ddns_address_type = T_A; - } else if (ddns_addr.len == 16) { - ddns_address_type = T_AAAA; + unsigned char *clientname; + dhcp_ddns_data_t *dataspace = NULL; + dns_namelist_t prereqlist, updatelist; + dns_fixedname_t zname0, pname0, uname0; + dns_name_t *zname = NULL, *pname, *uname; + + isc_sockaddrlist_t *zlist = NULL; + + /* Get a pointer to the clientname to make things easier. */ + clientname = (unsigned char *)ddns_cb->fwd_name.data; + + /* Extract and validate the type of the address. */ + if (ddns_cb->address.len == 4) { + ddns_cb->address_type = dns_rdatatype_a; + } else if (ddns_cb->address.len == 16) { + ddns_cb->address_type = dns_rdatatype_aaaa; } else { - return ISC_R_INVALIDARG; - } - strcpy(ddns_address, piaddr(ddns_addr)); - - /* - * The entity chosen to handle the A record for this client (either the - * client or the server) SHOULD delete the A record that was added when - * the lease was made to the client. - * - * In order to perform this delete, the updater prepares an UPDATE - * query which contains two prerequisites. The first prerequisite - * asserts that the DHCID RR exists whose data is the client identity - * described in Section 4.3. The second prerequisite asserts that the - * data in the A RR contains the IP address of the lease that has - * expired or been released. - * -- "Interaction between DHCP and DNS" - */ - - ISC_LIST_INIT (updqueue); - - /* - * DHCID RR exists, and matches client identity. - */ - updrec = minires_mkupdrec (S_PREREQ, - (const char *)ddns_fwd_name -> data, - C_IN, T_DHCID,0); - if (!updrec) { - result = ISC_R_NOMEMORY; - goto error; - } - - updrec -> r_data = ddns_dhcid -> data; - updrec -> r_size = ddns_dhcid -> len; - updrec -> r_opcode = YXRRSET; - - ISC_LIST_APPEND (updqueue, updrec, r_link); - - - /* - * Address RR (A/AAAA) matches the expiring lease. - */ - updrec = minires_mkupdrec (S_PREREQ, - (const char *)ddns_fwd_name -> data, - C_IN, ddns_address_type, 0); - if (!updrec) { - result = ISC_R_NOMEMORY; - goto error; - } - - updrec -> r_data = (unsigned char *)ddns_address; - updrec -> r_size = strlen (ddns_address); - updrec -> r_opcode = YXRRSET; - - ISC_LIST_APPEND (updqueue, updrec, r_link); - - - /* - * Delete appropriate Address RR (A/AAAA). - */ - updrec = minires_mkupdrec (S_UPDATE, - (const char *)ddns_fwd_name -> data, - C_IN, ddns_address_type, 0); - if (!updrec) { - result = ISC_R_NOMEMORY; - goto error; - } - - updrec -> r_data = (unsigned char *)ddns_address; - updrec -> r_size = strlen (ddns_address); - updrec -> r_opcode = DELETE; - - ISC_LIST_APPEND (updqueue, updrec, r_link); - - /* - * Attempt to perform the update. - */ - result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue)); - print_dns_status ((int)result, &updqueue); - - /* - * If the query fails, the updater MUST NOT delete the DNS name. It - * may be that the host whose lease on the server has expired has moved - * to another network and obtained a lease from a different server, - * which has caused the client's A RR to be replaced. It may also be - * that some other client has been configured with a name that matches - * the name of the DHCP client, and the policy was that the last client - * to specify the name would get the name. In this case, the DHCID RR - * will no longer match the updater's notion of the client-identity of - * the host pointed to by the DNS name. - * -- "Interaction between DHCP and DNS" - */ - - if (result != ISC_R_SUCCESS) { - /* If the rrset isn't there, we didn't need to do the - delete, which is success. */ - if (result == ISC_R_NXRRSET || result == ISC_R_NXDOMAIN) - result = ISC_R_SUCCESS; - goto error; - } - - while (!ISC_LIST_EMPTY (updqueue)) { - updrec = ISC_LIST_HEAD (updqueue); - ISC_LIST_UNLINK (updqueue, updrec, r_link); - minires_freeupdrec (updrec); + return DHCP_R_INVALIDARG; } /* - * If the deletion of the desired address succeeded (its A or AAAA - * RR was removed above), and there are zero other A or AAAA records - * left for this domain, then we can delete the DHCID record as well. - * We can't delete the DHCID record above because it's possible the - * client has more than one valid address added to this domain name, - * by this or other DHCP servers. - * - * Essentially, this final update is a cleanup operation that is only - * intended to succeed after the last address has been removed from - * DNS (which is only expected to happen after the client is not - * reasonably in possession of those addresses). + * If we already have a zone use it, otherwise try to lookup the + * zone in our cache. If we find one we will have a pointer to + * the zone that needs to be dereferenced when we are done with it. + * If we don't find one that is okay we'll let the DNS code try and + * find the information for us. */ - ISC_LIST_INIT (updqueue); - /* - * A RR does not exist. - */ - updrec = minires_mkupdrec(S_PREREQ, (const char *)ddns_fwd_name->data, - C_IN, T_A, 0); - if (updrec == NULL) { - result = ISC_R_NOMEMORY; - goto error; + if (ddns_cb->zone == NULL) { + result = find_cached_zone(ddns_cb, FIND_FORWARD); } - updrec->r_data = NULL; - updrec->r_size = 0; - updrec->r_opcode = NXRRSET; - - ISC_LIST_APPEND (updqueue, updrec, r_link); - /* - * AAAA RR does not exist. + * If we have a zone try to get any information we need + * from it - name, addresses and the key. The address + * and key may be empty the name can't be. */ - updrec = minires_mkupdrec(S_PREREQ, (const char *)ddns_fwd_name->data, - C_IN, T_AAAA, 0); + if (ddns_cb->zone) { + /* Set up the zone name for use by DNS */ + result = dhcp_isc_name(ddns_cb->zone_name, &zname0, &zname); + if (result != ISC_R_SUCCESS) { + log_error("Unable to build name for zone for " + "fwd update: %s %s", + ddns_cb->zone_name, + isc_result_totext(result)); + goto cleanup; + } - if (updrec == NULL) { - result = ISC_R_NOMEMORY; - goto error; + if (!(ISC_LIST_EMPTY(ddns_cb->zone_server_list))) { + /* If we have any addresses get them */ + zlist = &ddns_cb->zone_server_list; + } + + + if (ddns_cb->zone->key != NULL) { + /* + * Not having a key is fine, having a key + * but not a tsec is odd so we warn the user. + */ + /*sar*/ + /* should we do the warning? */ + tsec_key = ddns_cb->zone->key->tsec_key; + if (tsec_key == NULL) { + log_error("No tsec for use with key %s", + ddns_cb->zone->key->name); + } + } } - updrec->r_data = NULL; - updrec->r_size = 0; - updrec->r_opcode = NXRRSET; - - ISC_LIST_APPEND(updqueue, updrec, r_link); - - /* - * Delete appropriate DHCID RR. - */ - updrec = minires_mkupdrec (S_UPDATE, - (const char *)ddns_fwd_name -> data, - C_IN, T_DHCID, 0); - if (!updrec) { - result = ISC_R_NOMEMORY; - goto error; + /* Set up the DNS names for the prereq and update lists */ + if (((result = dhcp_isc_name(clientname, &pname0, &pname)) + != ISC_R_SUCCESS) || + ((result = dhcp_isc_name(clientname, &uname0, &uname)) + != ISC_R_SUCCESS)) { + log_error("Unable to build name for fwd update: %s %s", + clientname, isc_result_totext(result)); + goto cleanup; } - updrec -> r_data = ddns_dhcid -> data; - updrec -> r_size = ddns_dhcid -> len; - updrec -> r_opcode = DELETE; - - ISC_LIST_APPEND (updqueue, updrec, r_link); - - /* - * Attempt to perform the update. - */ - result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue)); - print_dns_status ((int)result, &updqueue); - - /* Fall through. */ - error: - - while (!ISC_LIST_EMPTY (updqueue)) { - updrec = ISC_LIST_HEAD (updqueue); - ISC_LIST_UNLINK (updqueue, updrec, r_link); - minires_freeupdrec (updrec); + /* Allocate the various isc dns library structures we may require. */ + dataspace = isc_mem_get(dhcp_gbl_ctx.mctx, sizeof(*dataspace) * 4); + if (dataspace == NULL) { + log_error("Unable to allocate memory for fwd update"); + result = ISC_R_NOMEMORY; + goto cleanup; } - return result; + ISC_LIST_INIT(prereqlist); + ISC_LIST_INIT(updatelist); + + switch(ddns_cb->state) { + case DDNS_STATE_ADD_FW_NXDOMAIN: + result = ddns_modify_fwd_add1(ddns_cb, dataspace, + pname, uname); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + ISC_LIST_APPEND(prereqlist, pname, link); + break; + case DDNS_STATE_ADD_FW_YXDHCID: + result = ddns_modify_fwd_add2(ddns_cb, dataspace, + pname, uname); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + + /* If we aren't doing conflict override we have entries + * in the pname list and we need to attach it to the + * prereqlist */ + + if ((ddns_cb->flags & DDNS_CONFLICT_OVERRIDE) == 0) { + ISC_LIST_APPEND(prereqlist, pname, link); + } + + break; + case DDNS_STATE_REM_FW_YXDHCID: + result = ddns_modify_fwd_rem1(ddns_cb, dataspace, + pname, uname); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + ISC_LIST_APPEND(prereqlist, pname, link); + break; + case DDNS_STATE_REM_FW_NXRR: + result = ddns_modify_fwd_rem2(ddns_cb, dataspace, + pname, uname); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + ISC_LIST_APPEND(prereqlist, pname, link); + break; + + default: + log_error("Invalid operation in ddns code."); + result = DHCP_R_INVALIDARG; + goto cleanup; + break; + } + + /* + * We always have an update list but may not have a prereqlist + * if we are doing conflict override. + */ + ISC_LIST_APPEND(updatelist, uname, link); + + /* send the message, cleanup and return the result */ + result = dns_client_startupdate(dhcp_gbl_ctx.dnsclient, + dns_rdataclass_in, zname, + &prereqlist, &updatelist, + zlist, tsec_key, + DNS_CLIENTRESOPT_ALLOWRUN, + dhcp_gbl_ctx.task, + ddns_interlude, + (void *)ddns_cb, + &ddns_cb->transaction); + + cleanup: + if (dataspace != NULL) { + isc_mem_put(dhcp_gbl_ctx.mctx, dataspace, + sizeof(*dataspace) * 4); + } + return(result); } +isc_result_t +ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb) +{ + isc_result_t result; + dns_tsec_t *tsec_key = NULL; + unsigned char *ptrname; + dhcp_ddns_data_t *dataspace = NULL; + dns_namelist_t updatelist; + dns_fixedname_t zname0, uname0; + dns_name_t *zname = NULL, *uname; + isc_sockaddrlist_t *zlist = NULL; + unsigned char buf[256]; + int buflen; + + /* + * Try to lookup the zone in the zone cache. As with the forward + * case it's okay if we don't have one, the DNS code will try to + * find something also if we succeed we will need to dereference + * the zone later. Unlike with the forward case we assume we won't + * have a pre-existing zone. + */ + result = find_cached_zone(ddns_cb, FIND_REVERSE); + if ((result == ISC_R_SUCCESS) && + !(ISC_LIST_EMPTY(ddns_cb->zone_server_list))) { + /* Set up the zone name for use by DNS */ + result = dhcp_isc_name(ddns_cb->zone_name, &zname0, &zname); + if (result != ISC_R_SUCCESS) { + log_error("Unable to build name for zone for " + "fwd update: %s %s", + ddns_cb->zone_name, + isc_result_totext(result)); + goto cleanup; + } + /* If we have any addresses get them */ + if (!(ISC_LIST_EMPTY(ddns_cb->zone_server_list))) { + zlist = &ddns_cb->zone_server_list; + } + + /* + * If we now have a zone try to get the key, NULL is okay, + * having a key but not a tsec is odd so we warn. + */ + /*sar*/ + /* should we do the warning if we have a key but no tsec? */ + if ((ddns_cb->zone != NULL) && (ddns_cb->zone->key != NULL)) { + tsec_key = ddns_cb->zone->key->tsec_key; + if (tsec_key == NULL) { + log_error("No tsec for use with key %s", + ddns_cb->zone->key->name); + } + } + } + + /* We must have a name for the update list */ + /* Get a pointer to the ptrname to make things easier. */ + ptrname = (unsigned char *)ddns_cb->rev_name.data; + + if ((result = dhcp_isc_name(ptrname, &uname0, &uname)) + != ISC_R_SUCCESS) { + log_error("Unable to build name for fwd update: %s %s", + ptrname, isc_result_totext(result)); + goto cleanup; + } + + /* + * Allocate the various isc dns library structures we may require. + * Allocating one blob avoids being halfway through the process + * and being unable to allocate as well as making the free easy. + */ + dataspace = isc_mem_get(dhcp_gbl_ctx.mctx, sizeof(*dataspace) * 2); + if (dataspace == NULL) { + log_error("Unable to allocate memory for fwd update"); + result = ISC_R_NOMEMORY; + goto cleanup; + } + + ISC_LIST_INIT(updatelist); + + /* + * Construct the update list + * We always delete what's currently there + * Delete PTR RR. + */ + result = make_dns_dataset(dns_rdataclass_any, dns_rdatatype_ptr, + &dataspace[0], NULL, 0, 0); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + ISC_LIST_APPEND(uname->list, &dataspace[0].rdataset, link); + + /* + * If we are updating the pointer we then add the new one + * Add PTR RR. + */ + if (ddns_cb->state == DDNS_STATE_ADD_PTR) { +#if 0 + /* + * I've left this dead code in the file for now in case + * we decide to try and get rid of the ns_name functions. + * sar + */ + + /* + * Need to convert pointer into on the wire representation + * We replace the '.' characters with the lengths of the + * next name and add a length to the beginning for the first + * name. + */ + if (ddns_cb->fwd_name.len == 1) { + /* the root */ + buf[0] = 0; + buflen = 1; + } else { + unsigned char *cp; + buf[0] = '.'; + memcpy(&buf[1], ddns_cb->fwd_name.data, + ddns_cb->fwd_name.len); + for(cp = buf + ddns_cb->fwd_name.len, buflen = 0; + cp != buf; + cp--) { + if (*cp == '.') { + *cp = buflen; + buflen = 0; + } else { + buflen++; + } + } + *cp = buflen; + buflen = ddns_cb->fwd_name.len + 1; + } +#endif + /* + * Need to convert pointer into on the wire representation + */ + if (MRns_name_pton((char *)ddns_cb->fwd_name.data, + buf, 256) == -1) { + goto cleanup; + } + buflen = 0; + while (buf[buflen] != 0) { + buflen += buf[buflen] + 1; + } + buflen++; + + result = make_dns_dataset(dns_rdataclass_in, + dns_rdatatype_ptr, + &dataspace[1], + buf, buflen, ddns_cb->ttl); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + ISC_LIST_APPEND(uname->list, &dataspace[1].rdataset, link); + } + + ISC_LIST_APPEND(updatelist, uname, link); + + /*sar*/ + /* + * for now I'll cleanup the dataset immediately, it would be + * more efficient to keep it around in case the signaturure failed + * and we wanted to retry it. + */ + /* send the message, cleanup and return the result */ + result = dns_client_startupdate((dns_client_t *)dhcp_gbl_ctx.dnsclient, + dns_rdataclass_in, zname, + NULL, &updatelist, + zlist, tsec_key, + DNS_CLIENTRESOPT_ALLOWRUN, + dhcp_gbl_ctx.task, + ddns_interlude, (void *)ddns_cb, + &ddns_cb->transaction); + cleanup: + if (dataspace != NULL) { + isc_mem_put(dhcp_gbl_ctx.mctx, dataspace, + sizeof(*dataspace) * 2); + } + return(result); +} + +void +ddns_cancel(dhcp_ddns_cb_t *ddns_cb) { + ddns_cb->flags |= DDNS_ABORT; + if (ddns_cb->transaction != NULL) { + dns_client_cancelupdate((dns_clientupdatetrans_t *) + ddns_cb->transaction); + } + ddns_cb->lease = NULL; +} + #endif /* NSUPDATE */ HASH_FUNCTIONS (dns_zone, const char *, struct dns_zone, dns_zone_hash_t, diff --git a/common/inet.c b/common/inet.c index d3aedc68..40c65349 100644 --- a/common/inet.c +++ b/common/inet.c @@ -376,13 +376,13 @@ range2cidr(struct iaddrcidrnetlist **result, int tmp; if (result == NULL) { - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (*result != NULL) { - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if ((lo == NULL) || (hi == NULL) || (lo->len != hi->len)) { - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } /* @@ -511,10 +511,10 @@ free_iaddrcidrnetlist(struct iaddrcidrnetlist **result) { struct iaddrcidrnetlist *p; if (result == NULL) { - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (*result == NULL) { - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } while (*result != NULL) { diff --git a/common/memory.c b/common/memory.c index a10a1923..74c67095 100644 --- a/common/memory.c +++ b/common/memory.c @@ -48,14 +48,14 @@ isc_result_t delete_group (struct group_object *group, int writep) group_hash_lookup (&d, group_name_hash, group -> name, strlen (group -> name), MDL); } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (!d) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* Also not okay to delete a group that's not the one in the hash table. */ if (d != group) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* If it's dynamic, and we're deleting it, we can just blow away the hash table entry. */ diff --git a/common/ns_name.c b/common/ns_name.c new file mode 100644 index 00000000..4879c89b --- /dev/null +++ b/common/ns_name.c @@ -0,0 +1,651 @@ +/* + * Copyright (c) 2004,2009 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996-2003 by 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. + * + * Internet Systems Consortium, Inc. + * 950 Charter Street + * Redwood City, CA 94063 + * + * http://www.isc.org/ + */ + +#ifndef lint +static const char rcsid[] = "$Id: ns_name.c,v 1.2 2009/10/28 04:12:29 sar Exp $"; +#endif + +#include + +#include +#include + +#include +#include +#include + +#include "minires.h" +#include "arpa/nameser.h" + +/* Data. */ + +static const char digits[] = "0123456789"; + +/* Forward. */ + +static int special(int); +static int printable(int); +static int dn_find(const u_char *, const u_char *, + const u_char * const *, + const u_char * const *); + +/* Public. */ + +/* + * MRns_name_ntop(src, dst, dstsiz) + * Convert an encoded domain name to printable ascii as per RFC1035. + * return: + * Number of bytes written to buffer, or -1 (with errno set) + * notes: + * The root is returned as "." + * All other domains are returned in non absolute form + */ +int +MRns_name_ntop(const u_char *src, char *dst, size_t dstsiz) { + const u_char *cp; + char *dn, *eom; + u_char c; + u_int n; + + cp = src; + dn = dst; + eom = dst + dstsiz; + + while ((n = *cp++) != 0) { + if ((n & NS_CMPRSFLGS) != 0) { + /* Some kind of compression pointer. */ + errno = EMSGSIZE; + return (-1); + } + if (dn != dst) { + if (dn >= eom) { + errno = EMSGSIZE; + return (-1); + } + *dn++ = '.'; + } + if (dn + n >= eom) { + errno = EMSGSIZE; + return (-1); + } + for ((void)NULL; n > 0; n--) { + c = *cp++; + if (special(c)) { + if (dn + 1 >= eom) { + errno = EMSGSIZE; + return (-1); + } + *dn++ = '\\'; + *dn++ = (char)c; + } else if (!printable(c)) { + if (dn + 3 >= eom) { + errno = EMSGSIZE; + return (-1); + } + *dn++ = '\\'; + *dn++ = digits[c / 100]; + *dn++ = digits[(c % 100) / 10]; + *dn++ = digits[c % 10]; + } else { + if (dn >= eom) { + errno = EMSGSIZE; + return (-1); + } + *dn++ = (char)c; + } + } + } + if (dn == dst) { + if (dn >= eom) { + errno = EMSGSIZE; + return (-1); + } + *dn++ = '.'; + } + if (dn >= eom) { + errno = EMSGSIZE; + return (-1); + } + *dn++ = '\0'; + return (dn - dst); +} + +/* + * MRns_name_pton(src, dst, dstsiz) + * Convert a ascii string into an encoded domain name as per RFC1035. + * return: + * -1 if it fails + * 1 if string was fully qualified + * 0 is string was not fully qualified + * notes: + * Enforces label and domain length limits. + */ + +int +MRns_name_pton(const char *src, u_char *dst, size_t dstsiz) { + u_char *label, *bp, *eom; + int c, n, escaped; + char *cp; + + escaped = 0; + bp = dst; + eom = dst + dstsiz; + label = bp++; + + while ((c = *src++) != 0) { + if (escaped) { + if ((cp = strchr(digits, c)) != NULL) { + n = (cp - digits) * 100; + if ((c = *src++) == 0 || + (cp = strchr(digits, c)) == NULL) { + errno = EMSGSIZE; + return (-1); + } + n += (cp - digits) * 10; + if ((c = *src++) == 0 || + (cp = strchr(digits, c)) == NULL) { + errno = EMSGSIZE; + return (-1); + } + n += (cp - digits); + if (n > 255) { + errno = EMSGSIZE; + return (-1); + } + c = n; + } + escaped = 0; + } else if (c == '\\') { + escaped = 1; + continue; + } else if (c == '.') { + c = (bp - label - 1); + if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */ + errno = EMSGSIZE; + return (-1); + } + if (label >= eom) { + errno = EMSGSIZE; + return (-1); + } + *label = c; + /* Fully qualified ? */ + if (*src == '\0') { + if (c != 0) { + if (bp >= eom) { + errno = EMSGSIZE; + return (-1); + } + *bp++ = '\0'; + } + if ((bp - dst) > MAXCDNAME) { + errno = EMSGSIZE; + return (-1); + } + return (1); + } + if (c == 0 || *src == '.') { + errno = EMSGSIZE; + return (-1); + } + label = bp++; + continue; + } + if (bp >= eom) { + errno = EMSGSIZE; + return (-1); + } + *bp++ = (u_char)c; + } + c = (bp - label - 1); + if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */ + errno = EMSGSIZE; + return (-1); + } + if (label >= eom) { + errno = EMSGSIZE; + return (-1); + } + *label = c; + if (c != 0) { + if (bp >= eom) { + errno = EMSGSIZE; + return (-1); + } + *bp++ = 0; + } + if ((bp - dst) > MAXCDNAME) { /* src too big */ + errno = EMSGSIZE; + return (-1); + } + return (0); +} + +/* + * MRns_name_ntol(src, dst, dstsiz) + * Convert a network strings labels into all lowercase. + * return: + * Number of bytes written to buffer, or -1 (with errno set) + * notes: + * Enforces label and domain length limits. + */ + +int +MRns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz) { + const u_char *cp; + u_char *dn, *eom; + u_char c; + u_int n; + + cp = src; + dn = dst; + eom = dst + dstsiz; + + if (dn >= eom) { + errno = EMSGSIZE; + return (-1); + } + while ((n = *cp++) != 0) { + if ((n & NS_CMPRSFLGS) != 0) { + /* Some kind of compression pointer. */ + errno = EMSGSIZE; + return (-1); + } + *dn++ = n; + if (dn + n >= eom) { + errno = EMSGSIZE; + return (-1); + } + for ((void)NULL; n > 0; n--) { + c = *cp++; + if (isupper(c)) + *dn++ = tolower(c); + else + *dn++ = c; + } + } + *dn++ = '\0'; + return (dn - dst); +} + +/* + * MRns_name_unpack(msg, eom, src, dst, dstsiz) + * Unpack a domain name from a message, source may be compressed. + * return: + * -1 if it fails, or consumed octets if it succeeds. + */ +int +MRns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, + u_char *dst, size_t dstsiz) +{ + const u_char *srcp, *dstlim; + u_char *dstp; + unsigned n; + int len; + int checked; + + len = -1; + checked = 0; + dstp = dst; + srcp = src; + dstlim = dst + dstsiz; + if (srcp < msg || srcp >= eom) { + errno = EMSGSIZE; + return (-1); + } + /* Fetch next label in domain name. */ + while ((n = *srcp++) != 0) { + /* Check for indirection. */ + switch (n & NS_CMPRSFLGS) { + case 0: + /* Limit checks. */ + if (dstp + n + 1 >= dstlim || srcp + n >= eom) { + errno = EMSGSIZE; + return (-1); + } + checked += n + 1; + *dstp++ = n; + memcpy(dstp, srcp, n); + dstp += n; + srcp += n; + break; + + case NS_CMPRSFLGS: + if (srcp >= eom) { + errno = EMSGSIZE; + return (-1); + } + if (len < 0) + len = srcp - src + 1; + srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff)); + if (srcp < msg || srcp >= eom) { /* Out of range. */ + errno = EMSGSIZE; + return (-1); + } + checked += 2; + /* + * Check for loops in the compressed name; + * if we've looked at the whole message, + * there must be a loop. + */ + if (checked >= eom - msg) { + errno = EMSGSIZE; + return (-1); + } + break; + + default: + errno = EMSGSIZE; + return (-1); /* flag error */ + } + } + *dstp = '\0'; + if (len < 0) + len = srcp - src; + return (len); +} + +/* + * MRns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr) + * Pack domain name 'domain' into 'comp_dn'. + * return: + * Size of the compressed name, or -1. + * notes: + * 'dnptrs' is an array of pointers to previous compressed names. + * dnptrs[0] is a pointer to the beginning of the message. The array + * ends with NULL. + * 'lastdnptr' is a pointer to the end of the array pointed to + * by 'dnptrs'. + * Side effects: + * The list of pointers in dnptrs is updated for labels inserted into + * the message as we compress the name. If 'dnptr' is NULL, we don't + * try to compress names. If 'lastdnptr' is NULL, we don't update the + * list. + */ +int +MRns_name_pack(const u_char *src, u_char *dst, unsigned dstsiz, + const u_char **dnptrs, const u_char **lastdnptr) +{ + u_char *dstp; + const u_char **cpp, **lpp, *eob, *msg; + const u_char *srcp; + unsigned n; + int l; + + srcp = src; + dstp = dst; + eob = dstp + dstsiz; + lpp = cpp = NULL; + if (dnptrs != NULL) { + if ((msg = *dnptrs++) != NULL) { + for (cpp = dnptrs; *cpp != NULL; cpp++) + (void)NULL; + lpp = cpp; /* end of list to search */ + } + } else + msg = NULL; + + /* make sure the domain we are about to add is legal */ + l = 0; + do { + n = *srcp; + if ((n & NS_CMPRSFLGS) != 0) { + errno = EMSGSIZE; + return (-1); + } + l += n + 1; + if (l > MAXCDNAME) { + errno = EMSGSIZE; + return (-1); + } + srcp += n + 1; + } while (n != 0); + + /* from here on we need to reset compression pointer array on error */ + srcp = src; + do { + /* Look to see if we can use pointers. */ + n = *srcp; + if (n != 0 && msg != NULL) { + l = dn_find(srcp, msg, (const u_char * const *)dnptrs, + (const u_char * const *)lpp); + if (l >= 0) { + if (dstp + 1 >= eob) { + goto cleanup; + } + *dstp++ = (l >> 8) | NS_CMPRSFLGS; + *dstp++ = l % 256; + return (dstp - dst); + } + /* Not found, save it. */ + if (lastdnptr != NULL && cpp < lastdnptr - 1 && + (dstp - msg) < 0x4000) { + *cpp++ = dstp; + *cpp = NULL; + } + } + /* copy label to buffer */ + if (n & NS_CMPRSFLGS) { /* Should not happen. */ + goto cleanup; + } + if (dstp + 1 + n >= eob) { + goto cleanup; + } + memcpy(dstp, srcp, n + 1); + srcp += n + 1; + dstp += n + 1; + } while (n != 0); + + if (dstp > eob) { +cleanup: + if (msg != NULL) + *lpp = NULL; + errno = EMSGSIZE; + return (-1); + } + return (dstp - dst); +} + +/* + * MRns_name_uncompress(msg, eom, src, dst, dstsiz) + * Expand compressed domain name to presentation format. + * return: + * Number of bytes read out of `src', or -1 (with errno set). + * note: + * Root domain returns as "." not "". + */ +int +MRns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src, + char *dst, size_t dstsiz) +{ + u_char tmp[NS_MAXCDNAME]; + int n; + + if ((n = MRns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1) + return (-1); + if (MRns_name_ntop(tmp, dst, dstsiz) == -1) + return (-1); + return (n); +} + +/* + * MRns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr) + * Compress a domain name into wire format, using compression pointers. + * return: + * Number of bytes consumed in `dst' or -1 (with errno set). + * notes: + * 'dnptrs' is an array of pointers to previous compressed names. + * dnptrs[0] is a pointer to the beginning of the message. + * The list ends with NULL. 'lastdnptr' is a pointer to the end of the + * array pointed to by 'dnptrs'. Side effect is to update the list of + * pointers for labels inserted into the message as we compress the name. + * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' + * is NULL, we don't update the list. + */ +int +MRns_name_compress(const char *src, u_char *dst, size_t dstsiz, + const u_char **dnptrs, const u_char **lastdnptr) +{ + u_char tmp[NS_MAXCDNAME]; + + if (MRns_name_pton(src, tmp, sizeof tmp) == -1) + return (-1); + return (MRns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr)); +} + +/* + * MRns_name_skip(ptrptr, eom) + * Advance *ptrptr to skip over the compressed name it points at. + * return: + * 0 on success, -1 (with errno set) on failure. + */ +int +MRns_name_skip(const u_char **ptrptr, const u_char *eom) { + const u_char *cp; + u_int n; + + cp = *ptrptr; + while (cp < eom && (n = *cp++) != 0) { + /* Check for indirection. */ + switch (n & NS_CMPRSFLGS) { + case 0: /* normal case, n == len */ + cp += n; + continue; + case NS_CMPRSFLGS: /* indirection */ + cp++; + break; + default: /* illegal type */ + errno = EMSGSIZE; + return (-1); + } + break; + } + if (cp > eom) { + errno = EMSGSIZE; + return (-1); + } + *ptrptr = cp; + return (0); +} + +/* Private. */ + +/* + * special(ch) + * Thinking in noninternationalized USASCII (per the DNS spec), + * is this characted special ("in need of quoting") ? + * return: + * boolean. + */ +static int +special(int ch) { + switch (ch) { + case 0x22: /* '"' */ + case 0x2E: /* '.' */ + case 0x3B: /* ';' */ + case 0x5C: /* '\\' */ + /* Special modifiers in zone files. */ + case 0x40: /* '@' */ + case 0x24: /* '$' */ + return (1); + default: + return (0); + } +} + +/* + * printable(ch) + * Thinking in noninternationalized USASCII (per the DNS spec), + * is this character visible and not a space when printed ? + * return: + * boolean. + */ +static int +printable(int ch) { + return (ch > 0x20 && ch < 0x7f); +} + +/* + * Thinking in noninternationalized USASCII (per the DNS spec), + * convert this character to lower case if it's upper case. + */ +static int +mklower(int ch) { + if (ch >= 0x41 && ch <= 0x5A) + return (ch + 0x20); + return (ch); +} + +/* + * dn_find(domain, msg, dnptrs, lastdnptr) + * Search for the counted-label name in an array of compressed names. + * return: + * offset from msg if found, or -1. + * notes: + * dnptrs is the pointer to the first name on the list, + * not the pointer to the start of the message. + */ +static int +dn_find(const u_char *domain, const u_char *msg, + const u_char * const *dnptrs, + const u_char * const *lastdnptr) +{ + const u_char *dn, *cp, *sp; + const u_char * const *cpp; + u_int n; + + for (cpp = dnptrs; cpp < lastdnptr; cpp++) { + dn = domain; + sp = cp = *cpp; + while ((n = *cp++) != 0) { + /* + * check for indirection + */ + switch (n & NS_CMPRSFLGS) { + case 0: /* normal case, n == len */ + if (n != *dn++) + goto next; + for ((void)NULL; n > 0; n--) + if (mklower(*dn++) != mklower(*cp++)) + goto next; + /* Is next root for both ? */ + if (*dn == '\0' && *cp == '\0') + return (sp - msg); + if (*dn) + continue; + goto next; + + case NS_CMPRSFLGS: /* indirection */ + cp = msg + (((n & 0x3f) << 8) | *cp); + break; + + default: /* illegal type */ + errno = EMSGSIZE; + return (-1); + } + } + next: ; + } + errno = ENOENT; + return (-1); +} diff --git a/common/parse.c b/common/parse.c index 35cea243..0d962609 100644 --- a/common/parse.c +++ b/common/parse.c @@ -1121,7 +1121,7 @@ parse_option_name (cfile, allocate, known, opt) unsigned code; if (opt == NULL) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; token = next_token (&val, (unsigned *)0, cfile); if (!is_identifier (token)) { @@ -1129,7 +1129,7 @@ parse_option_name (cfile, allocate, known, opt) "expecting identifier after option keyword."); if (token != SEMI) skip_to_semi (cfile); - return ISC_R_BADPARSE; + return DHCP_R_BADPARSE; } uname = dmalloc (strlen (val) + 1, MDL); if (!uname) @@ -1146,7 +1146,7 @@ parse_option_name (cfile, allocate, known, opt) parse_warn (cfile, "expecting identifier after '.'"); if (token != SEMI) skip_to_semi (cfile); - return ISC_R_BADPARSE; + return DHCP_R_BADPARSE; } /* Look up the option name hash table for the specified @@ -3374,7 +3374,7 @@ int parse_numeric_expression (expr, cfile, lose) } return 1; } - +#if defined (NSUPDATE_OLD) /* * dns-expression :== * UPDATE LPAREN ns-class COMMA ns-type COMMA data-expression COMMA @@ -3409,7 +3409,7 @@ int parse_dns_expression (expr, cfile, lose) } return 1; } - +#endif /* NSUPDATE_OLD */ /* Parse a subexpression that does not contain a binary operator. */ int parse_non_binary (expr, cfile, lose, context) @@ -3423,10 +3423,12 @@ int parse_non_binary (expr, cfile, lose, context) struct collection *col; struct expression *nexp, **ep; int known; + char *cptr; +#if defined (NSUPDATE_OLD) enum expr_op opcode; const char *s; - char *cptr; unsigned long u; +#endif isc_result_t status; unsigned len; @@ -3459,10 +3461,12 @@ int parse_non_binary (expr, cfile, lose, context) case TOKEN_NOT: token = next_token (&val, (unsigned *)0, cfile); +#if defined(NSUPDATE_OLD) if (context == context_dns) { token = peek_token (&val, (unsigned *)0, cfile); goto not_exists; } +#endif if (!expression_allocate (expr, MDL)) log_fatal ("can't allocate expression"); (*expr) -> op = expr_not; @@ -3506,8 +3510,10 @@ int parse_non_binary (expr, cfile, lose, context) break; case EXISTS: +#if defined(NSUPDATE_OLD) if (context == context_dns) goto ns_exists; +#endif token = next_token (&val, (unsigned *)0, cfile); if (!expression_allocate (expr, MDL)) log_fatal ("can't allocate expression"); @@ -3821,6 +3827,7 @@ int parse_non_binary (expr, cfile, lose, context) goto norparen; break; +#if defined(NSUPDATE_OLD) /* dns-update and dns-delete are present for historical purposes, but are deprecated in favor of ns-update in combination with update, delete, exists and not @@ -4098,7 +4105,7 @@ int parse_non_binary (expr, cfile, lose, context) if (token != RPAREN) goto norparen; break; - +#endif /* NSUPDATE_OLD */ case OPTION: case CONFIG_OPTION: if (!expression_allocate (expr, MDL)) @@ -4175,6 +4182,7 @@ int parse_non_binary (expr, cfile, lose, context) (*expr) -> op = expr_host_decl_name; break; +#if defined(NSUPDATE_OLD) case UPDATED_DNS_RR: token = next_token (&val, (unsigned *)0, cfile); @@ -4211,7 +4219,7 @@ int parse_non_binary (expr, cfile, lose, context) log_fatal ("can't allocate variable name."); strcpy ((*expr) -> data.variable, s); break; - +#endif /* NSUPDATE_OLD */ case PACKET: token = next_token (&val, (unsigned *)0, cfile); if (!expression_allocate (expr, MDL)) @@ -4423,7 +4431,7 @@ int parse_non_binary (expr, cfile, lose, context) goto ns_const; case NS_NOTAUTH: - known = ISC_R_NOTAUTH; + known = DHCP_R_NOTAUTH; goto ns_const; case NS_NOTIMP: @@ -4431,31 +4439,31 @@ int parse_non_binary (expr, cfile, lose, context) goto ns_const; case NS_NOTZONE: - known = ISC_R_NOTZONE; + known = DHCP_R_NOTZONE; goto ns_const; case NS_NXDOMAIN: - known = ISC_R_NXDOMAIN; + known = DHCP_R_NXDOMAIN; goto ns_const; case NS_NXRRSET: - known = ISC_R_NXRRSET; + known = DHCP_R_NXRRSET; goto ns_const; case NS_REFUSED: - known = ISC_R_REFUSED; + known = DHCP_R_REFUSED; goto ns_const; case NS_SERVFAIL: - known = ISC_R_SERVFAIL; + known = DHCP_R_SERVFAIL; goto ns_const; case NS_YXDOMAIN: - known = ISC_R_YXDOMAIN; + known = DHCP_R_YXDOMAIN; goto ns_const; case NS_YXRRSET: - known = ISC_R_YXRRSET; + known = DHCP_R_YXRRSET; goto ns_const; case BOOTING: diff --git a/common/print.c b/common/print.c index 0f1dbd7c..791dfb4b 100644 --- a/common/print.c +++ b/common/print.c @@ -1208,6 +1208,7 @@ void indent_spaces (FILE *file, int indent) } #if defined (NSUPDATE) +#if 0 void print_dns_status (int status, ns_updque *uq) { char obuf [1024]; @@ -1454,6 +1455,7 @@ void print_dns_status (int status, ns_updque *uq) else log_info ("%s", obuf); } +#endif #endif /* NSUPDATE */ /* Format the given time as "A; # B", where A is the format diff --git a/common/socket.c b/common/socket.c index f1185f62..24cd724a 100644 --- a/common/socket.c +++ b/common/socket.c @@ -116,6 +116,10 @@ if_register_socket(struct interface_info *info, int family, int sock; int flag; int domain; +#ifdef DHCPv6 + struct sockaddr_in6 *addr6; +#endif + struct sockaddr_in *addr; /* INSIST((family == AF_INET) || (family == AF_INET6)); */ @@ -133,28 +137,30 @@ if_register_socket(struct interface_info *info, int family, * address family. */ memset(&name, 0, sizeof(name)); + switch (family) { #ifdef DHCPv6 - if (family == AF_INET6) { - struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&name; - addr->sin6_family = AF_INET6; - addr->sin6_port = local_port; + case AF_INET6: + addr6 = (struct sockaddr_in6 *)&name; + addr6->sin6_family = AF_INET6; + addr6->sin6_port = local_port; /* XXX: What will happen to multicasts if this is nonzero? */ - memcpy(&addr->sin6_addr, + memcpy(&addr6->sin6_addr, &local_address6, - sizeof(addr->sin6_addr)); + sizeof(addr6->sin6_addr)); #ifdef HAVE_SA_LEN - addr->sin6_len = sizeof(*addr); + addr6->sin6_len = sizeof(*addr6); #endif - name_len = sizeof(*addr); + name_len = sizeof(*addr6); domain = PF_INET6; if ((info->flags & INTERFACE_STREAMS) == INTERFACE_UPSTREAM) { *do_multicast = 0; } - } else { -#else - { + break; #endif /* DHCPv6 */ - struct sockaddr_in *addr = (struct sockaddr_in *)&name; + + case AF_INET: + default: + addr = (struct sockaddr_in *)&name; addr->sin_family = AF_INET; addr->sin_port = local_port; memcpy(&addr->sin_addr, @@ -165,6 +171,7 @@ if_register_socket(struct interface_info *info, int family, #endif name_len = sizeof(*addr); domain = PF_INET; + break; } /* Make a socket... */ @@ -770,7 +777,7 @@ isc_result_t fallback_discard (object) struct interface_info *interface; if (object -> type != dhcp_type_interface) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; interface = (struct interface_info *)object; status = recvfrom (interface -> wfdesc, buf, sizeof buf, 0, diff --git a/common/tables.c b/common/tables.c index 95cd1463..077fbcda 100644 --- a/common/tables.c +++ b/common/tables.c @@ -843,14 +843,14 @@ option_reference(struct option **dest, struct option *src, const char * file, int line) { if (!dest || !src) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (*dest) { #if defined(POINTER_DEBUG) log_fatal("%s(%d): reference store into non-null pointer!", file, line); #else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } @@ -864,13 +864,13 @@ int option_dereference(struct option **dest, const char *file, int line) { if (!dest) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (!*dest) { #if defined (POINTER_DEBUG) log_fatal("%s(%d): dereference of null pointer!", file, line); #else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } @@ -878,7 +878,7 @@ option_dereference(struct option **dest, const char *file, int line) #if defined (POINTER_DEBUG) log_fatal("%s(%d): dereference of <= 0 refcnt!", file, line); #else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } diff --git a/common/tests/Makefile.am b/common/tests/Makefile.am index 1a2e5582..70eb50ad 100644 --- a/common/tests/Makefile.am +++ b/common/tests/Makefile.am @@ -6,5 +6,6 @@ TESTS = test_alloc test_alloc_SOURCES = test_alloc.c test_alloc_LDADD = ../libdhcp.a ../../tests/libt_api.a \ - ../../omapip/libomapi.a ../../dst/libdst.a ../../minires/libres.a + ../../omapip/libomapi.a ../../bind/lib/libdns.a \ + ../../bind/lib/libisc.a diff --git a/common/tree.c b/common/tree.c index d13b8a1e..6398948f 100644 --- a/common/tree.c +++ b/common/tree.c @@ -46,11 +46,6 @@ struct binding_scope *global_scope; static int do_host_lookup PROTO ((struct data_string *, struct dns_host_entry *)); -#ifdef NSUPDATE -struct __res_state resolver_state; -int resolver_inited = 0; -#endif - #define DS_SPRINTF_SIZE 128 /* @@ -650,8 +645,8 @@ int evaluate_expression (result, packet, lease, client_state, status = (evaluate_data_expression (&bv -> value.data, packet, lease, client_state, in_options, cfg_options, scope, expr, MDL)); +#if defined (NSUPDATE_OLD) } else if (is_dns_expression (expr)) { -#if defined (NSUPDATE) if (!binding_value_allocate (&bv, MDL)) return 0; bv -> type = binding_dns; @@ -705,7 +700,7 @@ int binding_value_dereference (struct binding_value **v, data_string_forget (&bv -> value.data, file, line); break; case binding_dns: -#if defined (NSUPDATE) +#if defined (NSUPDATE_OLD) if (bv -> value.dns) { if (bv -> value.dns -> r_data) { dfree (bv -> value.dns -> r_data_ephem, MDL); @@ -726,7 +721,7 @@ int binding_value_dereference (struct binding_value **v, return 1; } -#if defined (NSUPDATE) +#if defined (NSUPDATE_OLD) int evaluate_dns_expression (result, packet, lease, client_state, in_options, cfg_options, scope, expr) ns_updrec **result; @@ -988,7 +983,7 @@ int evaluate_dns_expression (result, packet, lease, client_state, in_options, expr -> op); return 0; } -#endif /* defined (NSUPDATE) */ +#endif /* defined (NSUPDATE_OLD) */ int evaluate_boolean_expression (result, packet, lease, client_state, in_options, cfg_options, scope, expr) @@ -1061,7 +1056,7 @@ int evaluate_boolean_expression (result, packet, lease, client_state, else *result = expr -> op == expr_not_equal; break; - +#if defined (NSUPDATE_OLD) case binding_dns: #if defined (NSUPDATE) /* XXX This should be a comparison for equal @@ -1074,7 +1069,7 @@ int evaluate_boolean_expression (result, packet, lease, client_state, *result = expr -> op == expr_not_equal; #endif break; - +#endif /* NSUPDATE_OLD */ case binding_function: if (bv -> value.fundef == obv -> value.fundef) *result = expr -> op == expr_equal; @@ -2404,11 +2399,12 @@ int evaluate_numeric_expression (result, packet, lease, client_state, { struct data_string data; int status, sleft, sright; -#if defined (NSUPDATE) +#if defined (NSUPDATE_OLD) ns_updrec *nut; ns_updque uq; -#endif struct expression *cur, *next; +#endif + struct binding *binding; struct binding_value *bv; unsigned long ileft, iright; @@ -2534,7 +2530,7 @@ int evaluate_numeric_expression (result, packet, lease, client_state, return 1; case expr_dns_transaction: -#if !defined (NSUPDATE) +#if !defined (NSUPDATE_OLD) return 0; #else if (!resolver_inited) { @@ -2578,7 +2574,7 @@ int evaluate_numeric_expression (result, packet, lease, client_state, minires_freeupdrec (tmp); } return status; -#endif /* NSUPDATE */ +#endif /* NSUPDATE_OLD */ case expr_variable_reference: if (scope && *scope) { diff --git a/configure.ac b/configure.ac index 1643f622..1274d463 100644 --- a/configure.ac +++ b/configure.ac @@ -483,10 +483,31 @@ AC_CHECK_MEMBER(struct msghdr.msg_control,, #include ]) +libbind = +AC_ARG_WITH(libbind, + AC_HELP_STRING([--with-libbind=PATH], + [bind includes and libraries are in PATH + (default is ./bind)]), + use_libbind="$withval", use_libbind="no") +case "$use_libbind" in +yes) + libbind="\${top_srcdir}/bind" + ;; +no) + libbind="\${top_srcdir}/bind" + ;; +*) + libbind="$use_libbind" + ;; +esac + # Append selected warning levels to CFLAGS before substitution (but after # AC_TRY_COMPILE & etc). CFLAGS="$CFLAGS $STD_CWARNINGS" +# Try to add the bind include directory +CFLAGS="$CFLAGS -I$libbind/include" + AC_OUTPUT([ Makefile client/Makefile @@ -495,7 +516,6 @@ AC_OUTPUT([ dhcpctl/Makefile dst/Makefile includes/Makefile - minires/Makefile omapip/Makefile relay/Makefile server/Makefile diff --git a/dhcpctl/Makefile.am b/dhcpctl/Makefile.am index 35f14620..61049bea 100644 --- a/dhcpctl/Makefile.am +++ b/dhcpctl/Makefile.am @@ -5,11 +5,11 @@ man_MANS = omshell.1 dhcpctl.3 EXTRA_DIST = $(man_MANS) omshell_SOURCES = omshell.c -omshell_LDADD = libdhcpctl.a ../common/libdhcp.a ../minires/libres.a \ - ../omapip/libomapi.a ../dst/libdst.a +omshell_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \ + ../bind/lib/libdns.a ../bind/lib/libisc.a libdhcpctl_a_SOURCES = dhcpctl.c callback.c remote.c cltest_SOURCES = cltest.c -cltest_LDADD = libdhcpctl.a ../common/libdhcp.a ../minires/libres.a \ - ../omapip/libomapi.a ../dst/libdst.a +cltest_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \ + ../bind/lib/libdns.a ../bind/lib/libisc.a \ No newline at end of file diff --git a/dhcpctl/callback.c b/dhcpctl/callback.c index d218fe71..6563fb62 100644 --- a/dhcpctl/callback.c +++ b/dhcpctl/callback.c @@ -84,7 +84,7 @@ isc_result_t dhcpctl_callback_set_value (omapi_object_t *h, omapi_typed_data_t *value) { if (h -> type != dhcpctl_callback_type) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (h -> inner && h -> inner -> type -> set_value) return (*(h -> inner -> type -> set_value)) @@ -98,7 +98,7 @@ isc_result_t dhcpctl_callback_get_value (omapi_object_t *h, omapi_value_t **value) { if (h -> type != dhcpctl_callback_type) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (h -> inner && h -> inner -> type -> get_value) return (*(h -> inner -> type -> get_value)) @@ -113,7 +113,7 @@ isc_result_t dhcpctl_callback_signal_handler (omapi_object_t *o, isc_result_t waitstatus; if (o -> type != dhcpctl_callback_type) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; p = (dhcpctl_callback_object_t *)o; /* Not a signal we recognize? */ @@ -142,7 +142,7 @@ isc_result_t dhcpctl_callback_destroy (omapi_object_t *h, { dhcpctl_callback_object_t *p; if (h -> type != dhcpctl_callback_type) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; p = (dhcpctl_callback_object_t *)h; if (p -> handle) omapi_object_dereference ((omapi_object_t **)&p -> handle, @@ -158,7 +158,7 @@ isc_result_t dhcpctl_callback_stuff_values (omapi_object_t *c, omapi_object_t *p) { if (p -> type != dhcpctl_callback_type) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (p -> inner && p -> inner -> type -> stuff_values) return (*(p -> inner -> type -> stuff_values)) (c, id, diff --git a/dhcpctl/cltest.c b/dhcpctl/cltest.c index 7e1b9633..aa7c6cfb 100644 --- a/dhcpctl/cltest.c +++ b/dhcpctl/cltest.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include "omapip/result.h" #include "dhcpctl.h" int main (int, char **); diff --git a/dhcpctl/dhcpctl.c b/dhcpctl/dhcpctl.c index e403d10d..bc93d7af 100644 --- a/dhcpctl/dhcpctl.c +++ b/dhcpctl/dhcpctl.c @@ -47,6 +47,11 @@ dhcpctl_status dhcpctl_initialize () { isc_result_t status; + /* Set up the isc and dns library managers */ + status = dhcp_context_create(); + if (status != ISC_R_SUCCESS) + return status; + status = omapi_init(); if (status != ISC_R_SUCCESS) return status; @@ -107,7 +112,7 @@ dhcpctl_status dhcpctl_connect (dhcpctl_handle *connection, (unsigned)port, authinfo); if (status == ISC_R_SUCCESS) return status; - if (status != ISC_R_INCOMPLETE) { + if (status != DHCP_R_INCOMPLETE) { omapi_object_dereference (connection, MDL); return status; } @@ -439,7 +444,7 @@ dhcpctl_status dhcpctl_object_update (dhcpctl_handle connection, dhcpctl_remote_object_t *ro; if (h -> type != dhcpctl_remote_type) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; ro = (dhcpctl_remote_object_t *)h; status = omapi_message_new (&message, MDL); @@ -488,7 +493,7 @@ dhcpctl_status dhcpctl_object_refresh (dhcpctl_handle connection, dhcpctl_remote_object_t *ro; if (h -> type != dhcpctl_remote_type) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; ro = (dhcpctl_remote_object_t *)h; status = omapi_message_new (&message, MDL); @@ -541,7 +546,7 @@ dhcpctl_status dhcpctl_object_remove (dhcpctl_handle connection, dhcpctl_remote_object_t *ro; if (h -> type != dhcpctl_remote_type) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; ro = (dhcpctl_remote_object_t *)h; status = omapi_message_new (&message, MDL); diff --git a/dhcpctl/omshell.c b/dhcpctl/omshell.c index fb0ca58a..6f27c820 100644 --- a/dhcpctl/omshell.c +++ b/dhcpctl/omshell.c @@ -38,7 +38,7 @@ #include #include #include -#include +//#include "result.h" #include #include "dhcpctl.h" #include "dhcpd.h" @@ -310,20 +310,31 @@ main(int argc, char **argv) { break; case KEY: - token = next_token (&val, (unsigned *)0, cfile); - if (!is_identifier (token)) { - printf ("usage: key \n"); - skip_to_semi (cfile); - break; + token = peek_token(&val, (unsigned *)0, cfile); + if (token == STRING) { + token = next_token (&val, (unsigned *)0, cfile); + if (!is_identifier (token)) { + printf ("usage: key \n"); + skip_to_semi (cfile); + break; + } + s = dmalloc (strlen (val) + 1, MDL); + if (!s) { + printf ("no memory for key name.\n"); + skip_to_semi (cfile); + break; + } + strcpy (s, val); + } else { + s = parse_host_name(cfile); + if (s == NULL) { + printf ("usage: key \n"); + skip_to_semi(cfile); + break; + } } - s = dmalloc (strlen (val) + 1, MDL); - if (!s) { - printf ("no memory for key name.\n"); - skip_to_semi (cfile); - break; - } - strcpy (s, val); name = s; + memset (&secret, 0, sizeof secret); if (!parse_base64 (&secret, cfile)) { skip_to_semi (cfile); diff --git a/dhcpctl/remote.c b/dhcpctl/remote.c index 48a6e5f6..ee204cb4 100644 --- a/dhcpctl/remote.c +++ b/dhcpctl/remote.c @@ -183,7 +183,7 @@ dhcpctl_status dhcpctl_open_object (dhcpctl_handle h, dhcpctl_remote_object_t *remote; if (h -> type != dhcpctl_remote_type) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; remote = (dhcpctl_remote_object_t *)h; status = omapi_message_new (&message, MDL); @@ -264,7 +264,7 @@ isc_result_t dhcpctl_remote_set_value (omapi_object_t *h, isc_result_t status; if (h -> type != dhcpctl_remote_type) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; ro = (dhcpctl_remote_object_t *)h; if (!omapi_ds_strcmp (name, "remote-handle")) { @@ -286,7 +286,7 @@ isc_result_t dhcpctl_remote_get_value (omapi_object_t *h, omapi_value_t **value) { if (h -> type != dhcpctl_remote_type) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (h -> inner && h -> inner -> type -> get_value) return (*(h -> inner -> type -> get_value)) @@ -301,7 +301,7 @@ isc_result_t dhcpctl_remote_signal_handler (omapi_object_t *o, omapi_typed_data_t *tv; if (o -> type != dhcpctl_remote_type) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; p = (dhcpctl_remote_object_t *)o; if (!strcmp (name, "updated")) { @@ -332,7 +332,7 @@ isc_result_t dhcpctl_remote_destroy (omapi_object_t *h, { dhcpctl_remote_object_t *p; if (h -> type != dhcpctl_remote_type) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; p = (dhcpctl_remote_object_t *)h; if (p -> handle) omapi_object_dereference ((omapi_object_t **)&p -> handle, @@ -351,7 +351,7 @@ isc_result_t dhcpctl_remote_stuff_values (omapi_object_t *c, omapi_object_t *p) { if (p -> type != dhcpctl_remote_type) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (p -> inner && p -> inner -> type -> stuff_values) return (*(p -> inner -> type -> stuff_values)) (c, id, diff --git a/dst/base64.c b/dst/base64.c index d0677df8..db70f681 100644 --- a/dst/base64.c +++ b/dst/base64.c @@ -47,7 +47,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: base64.c,v 1.3 2009/07/23 18:52:20 sar Exp $"; +static const char rcsid[] = "$Id: base64.c,v 1.4 2009/10/28 04:12:30 sar Exp $"; #endif /* not lint */ #include @@ -64,7 +64,6 @@ static const char rcsid[] = "$Id: base64.c,v 1.3 2009/07/23 18:52:20 sar Exp $"; #include -#include "minires/minires.h" #include "arpa/nameser.h" #define Assert(Cond) if (!(Cond)) abort() diff --git a/dst/dst_api.c b/dst/dst_api.c index 3cac622d..c42cf582 100644 --- a/dst/dst_api.c +++ b/dst/dst_api.c @@ -1,5 +1,5 @@ #ifndef LINT -static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/dst_api.c,v 1.7 2009/01/22 00:43:58 sar Exp $"; +static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/dst_api.c,v 1.8 2009/10/28 04:12:30 sar Exp $"; #endif /* @@ -54,7 +54,6 @@ static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/dst_api.c,v 1.7 2009 #include #include -#include "minires/minires.h" #include "arpa/nameser.h" #include "dst_internal.h" diff --git a/dst/dst_internal.h b/dst/dst_internal.h index 6d676707..72bb3662 100644 --- a/dst/dst_internal.h +++ b/dst/dst_internal.h @@ -157,5 +157,15 @@ void dst_s_put_int32( u_int8_t *buf, const u_int32_t val); # define DUMP(a,b,c,d) #endif +#if defined (MINIRES_LIB) +#define b64_pton MRb64_pton +#define b64_ntop MRb64_ntop + +int b64_pton (char const *, unsigned char *, size_t); +int b64_ntop (unsigned char const *, size_t, char *, size_t); + +#define USE_MD5 +#endif + #endif /* DST_INTERNAL_H */ diff --git a/dst/dst_support.c b/dst/dst_support.c index 0d4c3937..3522e2fa 100644 --- a/dst/dst_support.c +++ b/dst/dst_support.c @@ -1,4 +1,4 @@ -static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/dst_support.c,v 1.4 2007/12/06 00:50:22 dhankins Exp $"; +static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/dst_support.c,v 1.5 2009/10/28 04:12:30 sar Exp $"; /* @@ -28,7 +28,6 @@ static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/dst_support.c,v 1.4 #include #include -#include "minires/minires.h" #include "arpa/nameser.h" #include "dst_internal.h" diff --git a/dst/hmac_link.c b/dst/hmac_link.c index e26b9a7c..8fbf72be 100644 --- a/dst/hmac_link.c +++ b/dst/hmac_link.c @@ -1,6 +1,6 @@ #ifdef HMAC_MD5 #ifndef LINT -static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/hmac_link.c,v 1.3 2007/12/06 00:50:22 dhankins Exp $"; +static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/hmac_link.c,v 1.4 2009/10/28 04:12:30 sar Exp $"; #endif /* * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc. @@ -34,7 +34,6 @@ static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/hmac_link.c,v 1.3 20 #include #include -#include "minires/minires.h" #include "arpa/nameser.h" #include "dst_internal.h" diff --git a/dst/md5_dgst.c b/dst/md5_dgst.c index a80bf5fe..f134b8f4 100644 --- a/dst/md5_dgst.c +++ b/dst/md5_dgst.c @@ -83,7 +83,6 @@ #include #include #include "md5_locl.h" -#include "minires/minires.h" #ifdef USE_MD5 /* Added by ogud@tis.com 1998/1/26 */ diff --git a/dst/prandom.c b/dst/prandom.c index 2eae5f7b..a818cc1b 100644 --- a/dst/prandom.c +++ b/dst/prandom.c @@ -1,5 +1,5 @@ #ifndef LINT -static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/prandom.c,v 1.6 2007/11/30 21:51:43 fdupont Exp $"; +static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/prandom.c,v 1.7 2009/10/28 04:12:30 sar Exp $"; #endif /* * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc. @@ -34,7 +34,7 @@ static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/dst/prandom.c,v 1.6 2007 #include #include #define NEED_PRAND_CONF -#include "minires/minires.h" + #include "dst_internal.h" #include "arpa/nameser.h" diff --git a/includes/Makefile.am b/includes/Makefile.am index 725bfe32..b7738945 100644 --- a/includes/Makefile.am +++ b/includes/Makefile.am @@ -1,15 +1,9 @@ nobase_include_HEADERS = omapip/alloc.h omapip/buffer.h omapip/convert.h \ omapip/hash.h omapip/omapip.h omapip/omapip_p.h \ - omapip/trace.h \ - isc-dhcp/boolean.h isc-dhcp/formatcheck.h \ - isc-dhcp/lang.h isc-dhcp/mem.h isc-dhcp/result.h \ - isc-dhcp/types.h isc-dhcp/commandline.h \ - isc-dhcp/dst.h isc-dhcp/int.h isc-dhcp/list.h \ - isc-dhcp/print.h isc-dhcp/string.h + omapip/trace.h EXTRA_DIST = cdefs.h ctrace.h dhcp.h dhcp6.h dhcpd.h dhctoken.h failover.h \ heap.h inet.h osdep.h site.h statement.h tree.h t_api.h \ arpa/nameser.h arpa/nameser_compat.h \ - minires/minires.h minires/res_update.h minires/resolv.h \ netinet/if_ether.h netinet/ip.h netinet/ip_icmp.h netinet/udp.h diff --git a/includes/dhcpd.h b/includes/dhcpd.h index d39fc2c3..c8751eb8 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -71,9 +71,8 @@ #include "osdep.h" #include "arpa/nameser.h" -#if defined (NSUPDATE) -# include "minires/minires.h" -#endif + +#include "minires.h" struct hash_table; typedef struct hash_table group_hash_t; @@ -92,15 +91,16 @@ typedef time_t TIME; #define EOL '\n' #endif +#include +#include + #include "dhcp.h" #include "dhcp6.h" #include "statement.h" #include "tree.h" #include "inet.h" #include "dhctoken.h" -#include "heap.h" -#include #include #if !defined (BYTE_NAME_HASH_SIZE) @@ -512,6 +512,14 @@ struct lease { TIME cltt; /* Client last transaction time. */ u_int32_t last_xid; /* XID we sent in this lease's BNDUPD */ struct lease *next_pending; + + /* + * A pointer to the state of the ddns update for this lease. + * It should be set while the update is in progress and cleared + * when the update finishes. It can be used to cancel the + * update if we want to do a different update. + */ + struct dhcp_ddns_cb *ddns_cb; }; struct lease_state { @@ -1087,6 +1095,14 @@ struct client_state { * a no-op). */ void (*v6_handler)(struct packet *, struct client_state *); + + /* + * A pointer to the state of the ddns update for this lease. + * It should be set while the update is in progress and cleared + * when the update finishes. It can be used to cancel the + * update if we want to do a different update. + */ + struct dhcp_ddns_cb *ddns_cb; }; struct envadd_state { @@ -1181,6 +1197,7 @@ struct timeout { void *what; tvref_t ref; tvunref_t unref; + isc_timer_t *isc_timeout; }; struct eventqueue { @@ -1372,6 +1389,15 @@ struct iasubopt { int heap_index; /* index into heap, or -1 (internal use only) */ + + /* + * A pointer to the state of the ddns update for this lease. + * It should be set while the update is in progress and cleared + * when the update finishes. It can be used to cancel the + * update if we want to do a different update. + */ + struct dhcp_ddns_cb *ddns_cb; + }; struct ia_xx { @@ -1405,6 +1431,64 @@ struct ipv6_pool { struct subnet *subnet; /* subnet for this pool */ }; +/* Flags and state for dhcp_ddns_cb_t */ +#define DDNS_UPDATE_ADDR 0x01 +#define DDNS_UPDATE_PTR 0x02 +#define DDNS_INCLUDE_RRSET 0x04 +#define DDNS_CONFLICT_OVERRIDE 0x08 +#define DDNS_CLIENT_DID_UPDATE 0x10 +#define DDNS_EXECUTE_NEXT 0x20 +#define DDNS_ABORT 0x40 + +/* + * The following two groups are separate and we could reuse + * values but not reusing them may be useful in the future. + */ +#define DDNS_STATE_CLEANUP 0 // The previous step failed, cleanup + +#define DDNS_STATE_ADD_FW_NXDOMAIN 1 +#define DDNS_STATE_ADD_FW_YXDHCID 2 +#define DDNS_STATE_ADD_PTR 3 + +#define DDNS_STATE_REM_FW_YXDHCID 17 +#define DDNS_STATE_REM_FW_NXRR 18 +#define DDNS_STATE_REM_PTR 19 + +struct dhcp_ddns_cb; + +typedef void (*ddns_action_t)(struct dhcp_ddns_cb *ddns_cb, + isc_result_t result); + +typedef struct dhcp_ddns_cb { + struct data_string fwd_name; + struct data_string rev_name; + struct data_string dhcid; + struct iaddr address; + int address_type; + + unsigned long ttl; + + unsigned char zone_name[DHCP_MAXDNS_WIRE]; + isc_sockaddrlist_t zone_server_list; + isc_sockaddr_t zone_addrs[DHCP_MAXNS]; + int zone_addr_count; + struct dns_zone *zone; + + int flags; + TIME timeout; + int state; + ddns_action_t cur_func; + + struct dhcp_ddns_cb * next_op; + + /* Lease or client state that triggered the ddns operation */ + void *lease; + struct binding_scope **scope; + + void *transaction; + void *dataspace; +} dhcp_ddns_cb_t; + extern struct ipv6_pool **pools; extern int num_pools; @@ -1743,7 +1827,7 @@ void parse_server_duid_conf(struct parse *cfile); /* ddns.c */ int ddns_updates(struct packet *, struct lease *, struct lease *, struct iasubopt *, struct iasubopt *, struct option_state *); -int ddns_removals(struct lease *, struct iasubopt *); +int ddns_removals(struct lease *, struct iasubopt *, struct dhcp_ddns_cb *); /* parse.c */ void add_enumeration (struct enumeration *); @@ -1849,7 +1933,7 @@ int evaluate_expression (struct binding_value **, struct packet *, struct binding_scope **, struct expression *, const char *, int); int binding_value_dereference (struct binding_value **, const char *, int); -#if defined (NSUPDATE) +#if defined (NSUPDATE_OLD) int evaluate_dns_expression PROTO ((ns_updrec **, struct packet *, struct lease *, struct client_state *, @@ -2137,8 +2221,10 @@ int token_print_indent (FILE *, int, int, const char *, const char *, const char *); void indent_spaces (FILE *, int); #if defined (NSUPDATE) +#if 0 void print_dns_status (int, ns_updque *); #endif +#endif const char *print_time(TIME); void get_hw_addr(const char *name, struct hardware *hw); @@ -2540,8 +2626,9 @@ isc_result_t dhclient_interface_startup_hook (struct interface_info *); void dhclient_schedule_updates(struct client_state *client, struct iaddr *addr, int offset); void client_dns_update_timeout (void *cp); -isc_result_t client_dns_update(struct client_state *client, int, int, - struct iaddr *); +isc_result_t client_dns_update(struct client_state *client, + dhcp_ddns_cb_t *ddns_cb); +void client_dns_remove(struct client_state *client, struct iaddr *addr); void dhcpv4_client_assignments(void); void dhcpv6_client_assignments(void); @@ -2685,13 +2772,15 @@ isc_result_t enter_dns_zone (struct dns_zone *); isc_result_t dns_zone_lookup (struct dns_zone **, const char *); int dns_zone_dereference PROTO ((struct dns_zone **, const char *, int)); #if defined (NSUPDATE) -isc_result_t find_cached_zone (const char *, ns_class, char *, - size_t, struct in_addr *, int, int *, - struct dns_zone **); +#define FIND_FORWARD 0 +#define FIND_REVERSE 1 +isc_result_t find_cached_zone (dhcp_ddns_cb_t *, int); void forget_zone (struct dns_zone **); void repudiate_zone (struct dns_zone **); -void cache_found_zone (ns_class, char *, struct in_addr *, int); +//void cache_found_zone (ns_class, char *, struct in_addr *, int); int get_dhcid (struct data_string *, int, const u_int8_t *, unsigned); +void dhcid_tolease (struct data_string *, struct data_string *); +isc_result_t dhcid_fromlease (struct data_string *, struct data_string *); isc_result_t ddns_update_fwd(struct data_string *, struct iaddr, struct data_string *, unsigned long, unsigned, unsigned); @@ -3318,3 +3407,17 @@ void mark_hosts_unavailable(void); void mark_phosts_unavailable(void); void mark_interfaces_unavailable(void); +dhcp_ddns_cb_t *ddns_cb_alloc(const char *file, int line); +void ddns_cb_free (dhcp_ddns_cb_t *ddns_cb, const char *file, int line); +void ddns_cb_forget_zone (dhcp_ddns_cb_t *ddns_cb); + +//void *key_from_zone(struct dns_zone *zone); + +isc_result_t +ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb); + +isc_result_t +ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb); + +void +ddns_cancel(dhcp_ddns_cb_t *ddns_cb); diff --git a/includes/isc-dhcp/commandline.h b/includes/isc-dhcp/commandline.h deleted file mode 100644 index a833167e..00000000 --- a/includes/isc-dhcp/commandline.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and/or 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: commandline.h,v 1.2 2007/11/16 11:04:11 shane Exp $ */ - -#ifndef ISC_COMMANDLINE_H -#define ISC_COMMANDLINE_H 1 - -/*! \file isc/commandline.h */ - -#include -#include -/*#include */ - -/*% Index into parent argv vector. */ -extern int isc_commandline_index; -/*% Character checked for validity. */ -extern int isc_commandline_option; -/*% Argument associated with option. */ -extern char *isc_commandline_argument; -/*% For printing error messages. */ -extern char *isc_commandline_progname; -/*% Print error message. */ -extern isc_boolean_t isc_commandline_errprint; -/*% Reset getopt. */ -extern isc_boolean_t isc_commandline_reset; - -ISC_LANG_BEGINDECLS - -/*% parse command line */ -int -isc_commandline_parse(int argc, char * const *argv, const char *options); - -ISC_LANG_ENDDECLS - -#endif /* ISC_COMMANDLINE_H */ diff --git a/includes/isc-dhcp/formatcheck.h b/includes/isc-dhcp/formatcheck.h deleted file mode 100644 index 7f4e3cf3..00000000 --- a/includes/isc-dhcp/formatcheck.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and/or 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: formatcheck.h,v 1.2 2007/11/16 11:04:11 shane Exp $ */ - -#ifndef ISC_FORMATCHECK_H -#define ISC_FORMATCHECK_H 1 - -/*! \file isc/formatcheck.h */ - -/*% - * ISC_FORMAT_PRINTF(). - * - * \li fmt is the location of the format string parameter. - * \li args is the location of the first argument (or 0 for no argument checking). - * - * Note: - * \li The first parameter is 1, not 0. - */ -#ifdef __GNUC__ -#define ISC_FORMAT_PRINTF(fmt, args) __attribute__((__format__(__printf__, fmt, args))) -#else -#define ISC_FORMAT_PRINTF(fmt, args) -#endif - -#endif /* ISC_FORMATCHECK_H */ diff --git a/includes/isc-dhcp/int.h b/includes/isc-dhcp/int.h deleted file mode 100644 index e692f465..00000000 --- a/includes/isc-dhcp/int.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1999-2003 by 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. - * - * Internet Systems Consortium, Inc. - * 950 Charter Street - * Redwood City, CA 94063 - * - * https://www.isc.org/ - */ - -#ifndef ISC_INT_H -#define ISC_INT_H 1 - -#include - -ISC_LANG_BEGINDECLS - -typedef char isc_int8_t; -typedef unsigned char isc_uint8_t; -typedef short isc_int16_t; -typedef unsigned short isc_uint16_t; -typedef int isc_int32_t; -typedef unsigned int isc_uint32_t; -typedef long long isc_int64_t; -typedef unsigned long long isc_uint64_t; - -ISC_LANG_ENDDECLS - -#endif /* ISC_INT_H */ diff --git a/includes/isc-dhcp/lang.h b/includes/isc-dhcp/lang.h deleted file mode 100644 index 01f12bf2..00000000 --- a/includes/isc-dhcp/lang.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1999-2003 by 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. - * - * Internet Systems Consortium, Inc. - * 950 Charter Street - * Redwood City, CA 94063 - * - * https://www.isc.org/ - */ - -#ifndef ISC_LANG_H -#define ISC_LANG_H 1 - -#ifdef __cplusplus -#define ISC_LANG_BEGINDECLS extern "C" { -#define ISC_LANG_ENDDECLS } -#else -#define ISC_LANG_BEGINDECLS -#define ISC_LANG_ENDDECLS -#endif - -#endif /* ISC_LANG_H */ diff --git a/includes/isc-dhcp/list.h b/includes/isc-dhcp/list.h deleted file mode 100644 index 689d1799..00000000 --- a/includes/isc-dhcp/list.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1997-2003 by 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. - * - * Internet Systems Consortium, Inc. - * 950 Charter Street - * Redwood City, CA 94063 - * - * https://www.isc.org/ - */ - -#ifndef ISC_LIST_H -#define ISC_LIST_H 1 - -#define ISC_LIST(type) struct { type *head, *tail; } -#define ISC_LIST_INIT(list) \ - do { (list).head = NULL; (list).tail = NULL; } while (0) - -#define ISC_LINK(type) struct { type *prev, *next; } -#define ISC_LINK_INIT(elt, link) \ - do { \ - (elt)->link.prev = (void *)(-1); \ - (elt)->link.next = (void *)(-1); \ - } while (0) -#define ISC_LINK_LINKED(elt, link) ((elt)->link.prev != (void *)(-1)) - -#define ISC_LIST_HEAD(list) ((list).head) -#define ISC_LIST_TAIL(list) ((list).tail) -#define ISC_LIST_EMPTY(list) ((list).head == NULL) - -#define ISC_LIST_PREPEND(list, elt, link) \ - do { \ - if ((list).head != NULL) \ - (list).head->link.prev = (elt); \ - else \ - (list).tail = (elt); \ - (elt)->link.prev = NULL; \ - (elt)->link.next = (list).head; \ - (list).head = (elt); \ - } while (0) - -#define ISC_LIST_APPEND(list, elt, link) \ - do { \ - if ((list).tail != NULL) \ - (list).tail->link.next = (elt); \ - else \ - (list).head = (elt); \ - (elt)->link.prev = (list).tail; \ - (elt)->link.next = NULL; \ - (list).tail = (elt); \ - } while (0) - -#define ISC_LIST_UNLINK(list, elt, link) \ - do { \ - if ((elt)->link.next != NULL) \ - (elt)->link.next->link.prev = (elt)->link.prev; \ - else \ - (list).tail = (elt)->link.prev; \ - if ((elt)->link.prev != NULL) \ - (elt)->link.prev->link.next = (elt)->link.next; \ - else \ - (list).head = (elt)->link.next; \ - (elt)->link.prev = (void *)(-1); \ - (elt)->link.next = (void *)(-1); \ - } while (0) - -#define ISC_LIST_PREV(elt, link) ((elt)->link.prev) -#define ISC_LIST_NEXT(elt, link) ((elt)->link.next) - -#define ISC_LIST_INSERTBEFORE(list, before, elt, link) \ - do { \ - if ((before)->link.prev == NULL) \ - ISC_LIST_PREPEND(list, elt, link); \ - else { \ - (elt)->link.prev = (before)->link.prev; \ - (before)->link.prev = (elt); \ - (elt)->link.prev->link.next = (elt); \ - (elt)->link.next = (before); \ - } \ - } while (0) - -#define ISC_LIST_INSERTAFTER(list, after, elt, link) \ - do { \ - if ((after)->link.next == NULL) \ - ISC_LIST_APPEND(list, elt, link); \ - else { \ - (elt)->link.next = (after)->link.next; \ - (after)->link.next = (elt); \ - (elt)->link.next->link.prev = (elt); \ - (elt)->link.prev = (after); \ - } \ - } while (0) - -#define ISC_LIST_APPENDLIST(list1, list2, link) \ - do { \ - if (ISC_LIST_EMPTY(list1)) \ - (list1) = (list2); \ - else if (!ISC_LIST_EMPTY(list2)) { \ - (list1).tail->link.next = (list2).head; \ - (list2).head->link.prev = (list1).tail; \ - (list1).tail = (list2).tail; \ - (list2).head = NULL; \ - (list2).tail = NULL; \ - } \ - } while (0) - -#define ISC_LIST_ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link) -#define ISC_LIST_DEQUEUE(list, elt, link) ISC_LIST_UNLINK(list, elt, link) - -#endif /* ISC_LIST_H */ diff --git a/includes/isc-dhcp/mem.h b/includes/isc-dhcp/mem.h deleted file mode 100644 index 394ef85a..00000000 --- a/includes/isc-dhcp/mem.h +++ /dev/null @@ -1,552 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1997-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and/or 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: mem.h,v 1.2 2007/11/16 11:04:11 shane Exp $ */ - -#ifndef ISC_MEM_H -#define ISC_MEM_H 1 - -/*! \file isc/mem.h */ - -#include - -#include -/*#include */ -/*#include */ -#include -/*#include */ -#include - -ISC_LANG_BEGINDECLS - -#define ISC_MEM_LOWATER 0 -#define ISC_MEM_HIWATER 1 -typedef void (*isc_mem_water_t)(void *, int); - -typedef void * (*isc_memalloc_t)(void *, size_t); -typedef void (*isc_memfree_t)(void *, void *); - -/*% - * Define ISC_MEM_DEBUG=1 to make all functions that free memory - * set the pointer being freed to NULL after being freed. - * This is the default; set ISC_MEM_DEBUG=0 to disable it. - */ -#ifndef ISC_MEM_DEBUG -#define ISC_MEM_DEBUG 1 -#endif - -/*% - * Define ISC_MEM_TRACKLINES=1 to turn on detailed tracing of memory - * allocation and freeing by file and line number. - */ -#ifndef ISC_MEM_TRACKLINES -#define ISC_MEM_TRACKLINES 1 -#endif - -/*% - * Define ISC_MEM_CHECKOVERRUN=1 to turn on checks for using memory outside - * the requested space. This will increase the size of each allocation. - */ -#ifndef ISC_MEM_CHECKOVERRUN -#define ISC_MEM_CHECKOVERRUN 1 -#endif - -/*% - * Define ISC_MEM_FILL=1 to fill each block of memory returned to the system - * with the byte string '0xbe'. This helps track down uninitialized pointers - * and the like. On freeing memory, the space is filled with '0xde' for - * the same reasons. - */ -#ifndef ISC_MEM_FILL -#define ISC_MEM_FILL 1 -#endif - -/*% - * Define ISC_MEMPOOL_NAMES=1 to make memory pools store a symbolic - * name so that the leaking pool can be more readily identified in - * case of a memory leak. - */ -#ifndef ISC_MEMPOOL_NAMES -#define ISC_MEMPOOL_NAMES 1 -#endif - -extern unsigned int isc_mem_debugging; -/*@{*/ -#define ISC_MEM_DEBUGTRACE 0x00000001U -#define ISC_MEM_DEBUGRECORD 0x00000002U -#define ISC_MEM_DEBUGUSAGE 0x00000004U -#define ISC_MEM_DEBUGSIZE 0x00000008U -#define ISC_MEM_DEBUGCTX 0x00000010U -#define ISC_MEM_DEBUGALL 0x0000001FU -/*!< - * The variable isc_mem_debugging holds a set of flags for - * turning certain memory debugging options on or off at - * runtime. Its is intialized to the value ISC_MEM_DEGBUGGING, - * which is 0 by default but may be overridden at compile time. - * The following flags can be specified: - * - * \li #ISC_MEM_DEBUGTRACE - * Log each allocation and free to isc_lctx. - * - * \li #ISC_MEM_DEBUGRECORD - * Remember each allocation, and match them up on free. - * Crash if a free doesn't match an allocation. - * - * \li #ISC_MEM_DEBUGUSAGE - * If a hi_water mark is set, print the maximium inuse memory - * every time it is raised once it exceeds the hi_water mark. - * - * \li #ISC_MEM_DEBUGSIZE - * Check the size argument being passed to isc_mem_put() matches - * that passed to isc_mem_get(). - * - * \li #ISC_MEM_DEBUGCTX - * Check the mctx argument being passed to isc_mem_put() matches - * that passed to isc_mem_get(). - */ -/*@}*/ - -#if ISC_MEM_TRACKLINES -#define _ISC_MEM_FILELINE , __FILE__, __LINE__ -#define _ISC_MEM_FLARG , const char *, int -#else -#define _ISC_MEM_FILELINE -#define _ISC_MEM_FLARG -#endif - -/*! - * Define ISC_MEM_USE_INTERNAL_MALLOC=1 to use the internal malloc() - * implementation in preference to the system one. The internal malloc() - * is very space-efficient, and quite fast on uniprocessor systems. It - * performs poorly on multiprocessor machines. - * JT: we can overcome the performance issue on multiprocessor machines - * by carefully separating memory contexts. - */ - -#ifndef ISC_MEM_USE_INTERNAL_MALLOC -#define ISC_MEM_USE_INTERNAL_MALLOC 1 -#endif - -/* - * Flags for isc_mem_create2()calls. - */ -#define ISC_MEMFLAG_NOLOCK 0x00000001 /* no lock is necessary */ -#define ISC_MEMFLAG_INTERNAL 0x00000002 /* use internal malloc */ -#if ISC_MEM_USE_INTERNAL_MALLOC -#define ISC_MEMFLAG_DEFAULT ISC_MEMFLAG_INTERNAL -#else -#define ISC_MEMFLAG_DEFAULT 0 -#endif - - -#define isc_mem_get(c, s) isc__mem_get((c), (s) _ISC_MEM_FILELINE) -#define isc_mem_allocate(c, s) isc__mem_allocate((c), (s) _ISC_MEM_FILELINE) -#define isc_mem_strdup(c, p) isc__mem_strdup((c), (p) _ISC_MEM_FILELINE) -#define isc_mempool_get(c) isc__mempool_get((c) _ISC_MEM_FILELINE) - -/*% - * isc_mem_putanddetach() is a convienence function for use where you - * have a structure with an attached memory context. - * - * Given: - * - * \code - * struct { - * ... - * isc_mem_t *mctx; - * ... - * } *ptr; - * - * isc_mem_t *mctx; - * - * isc_mem_putanddetach(&ptr->mctx, ptr, sizeof(*ptr)); - * \endcode - * - * is the equivalent of: - * - * \code - * mctx = NULL; - * isc_mem_attach(ptr->mctx, &mctx); - * isc_mem_detach(&ptr->mctx); - * isc_mem_put(mctx, ptr, sizeof(*ptr)); - * isc_mem_detach(&mctx); - * \endcode - */ - -#if ISC_MEM_DEBUG -#define isc_mem_put(c, p, s) \ - do { \ - isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE); \ - (p) = NULL; \ - } while (0) -#define isc_mem_putanddetach(c, p, s) \ - do { \ - isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE); \ - (p) = NULL; \ - } while (0) -#define isc_mem_free(c, p) \ - do { \ - isc__mem_free((c), (p) _ISC_MEM_FILELINE); \ - (p) = NULL; \ - } while (0) -#define isc_mempool_put(c, p) \ - do { \ - isc__mempool_put((c), (p) _ISC_MEM_FILELINE); \ - (p) = NULL; \ - } while (0) -#else -#define isc_mem_put(c, p, s) isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE) -#define isc_mem_putanddetach(c, p, s) \ - isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE) -#define isc_mem_free(c, p) isc__mem_free((c), (p) _ISC_MEM_FILELINE) -#define isc_mempool_put(c, p) isc__mempool_put((c), (p) _ISC_MEM_FILELINE) -#endif - -/*@{*/ -isc_result_t -isc_mem_create(size_t max_size, size_t target_size, - isc_mem_t **mctxp); - -isc_result_t -isc_mem_create2(size_t max_size, size_t target_size, - isc_mem_t **mctxp, unsigned int flags); - -isc_result_t -isc_mem_createx(size_t max_size, size_t target_size, - isc_memalloc_t memalloc, isc_memfree_t memfree, - void *arg, isc_mem_t **mctxp); - -isc_result_t -isc_mem_createx2(size_t max_size, size_t target_size, - isc_memalloc_t memalloc, isc_memfree_t memfree, - void *arg, isc_mem_t **mctxp, unsigned int flags); - -/*!< - * \brief Create a memory context. - * - * 'max_size' and 'target_size' are tuning parameters. When - * ISC_MEMFLAG_INTERNAL is set, allocations smaller than 'max_size' - * will be satisfied by getting blocks of size 'target_size' from the - * system allocator and breaking them up into pieces; larger allocations - * will use the system allocator directly. If 'max_size' and/or - * 'target_size' are zero, default values will be * used. When - * ISC_MEMFLAG_INTERNAL is not set, 'target_size' is ignored. - * - * 'max_size' is also used to size the statistics arrays and the array - * used to record active memory when ISC_MEM_DEBUGRECORD is set. Settin - * 'max_size' too low can have detrimental effects on performance. - * - * A memory context created using isc_mem_createx() will obtain - * memory from the system by calling 'memalloc' and 'memfree', - * passing them the argument 'arg'. A memory context created - * using isc_mem_create() will use the standard library malloc() - * and free(). - * - * If ISC_MEMFLAG_NOLOCK is set in 'flags', the corresponding memory context - * will be accessed without locking. The user who creates the context must - * ensure there be no race. Since this can be a source of bug, it is generally - * inadvisable to use this flag unless the user is very sure about the race - * condition and the access to the object is highly performance sensitive. - * - * Requires: - * mctxp != NULL && *mctxp == NULL */ -/*@}*/ - -/*@{*/ -void -isc_mem_attach(isc_mem_t *, isc_mem_t **); -void -isc_mem_detach(isc_mem_t **); -/*!< - * \brief Attach to / detach from a memory context. - * - * This is intended for applications that use multiple memory contexts - * in such a way that it is not obvious when the last allocations from - * a given context has been freed and destroying the context is safe. - * - * Most applications do not need to call these functions as they can - * simply create a single memory context at the beginning of main() - * and destroy it at the end of main(), thereby guaranteeing that it - * is not destroyed while there are outstanding allocations. - */ -/*@}*/ - -void -isc_mem_destroy(isc_mem_t **); -/*%< - * Destroy a memory context. - */ - -isc_result_t -isc_mem_ondestroy(isc_mem_t *ctx, - isc_task_t *task, - isc_event_t **event); -/*%< - * Request to be notified with an event when a memory context has - * been successfully destroyed. - */ - -void -isc_mem_stats(isc_mem_t *mctx, FILE *out); -/*%< - * Print memory usage statistics for 'mctx' on the stream 'out'. - */ - -void -isc_mem_setdestroycheck(isc_mem_t *mctx, - isc_boolean_t on); -/*%< - * If 'on' is ISC_TRUE, 'mctx' will check for memory leaks when - * destroyed and abort the program if any are present. - */ - -/*@{*/ -void -isc_mem_setquota(isc_mem_t *, size_t); -size_t -isc_mem_getquota(isc_mem_t *); -/*%< - * Set/get the memory quota of 'mctx'. This is a hard limit - * on the amount of memory that may be allocated from mctx; - * if it is exceeded, allocations will fail. - */ -/*@}*/ - -size_t -isc_mem_inuse(isc_mem_t *mctx); -/*%< - * Get an estimate of the number of memory in use in 'mctx', in bytes. - * This includes quantization overhead, but does not include memory - * allocated from the system but not yet used. - */ - -void -isc_mem_setwater(isc_mem_t *mctx, isc_mem_water_t water, void *water_arg, - size_t hiwater, size_t lowater); -/*%< - * Set high and low water marks for this memory context. - * - * When the memory - * usage of 'mctx' exceeds 'hiwater', '(water)(water_arg, #ISC_MEM_HIWATER)' - * will be called. When the usage drops below 'lowater', 'water' will - * again be called, this time with #ISC_MEM_LOWATER. - * - * If 'water' is NULL then 'water_arg', 'hi_water' and 'lo_water' are - * ignored and the state is reset. - * - * Requires: - * - * 'water' is not NULL. - * hi_water >= lo_water - */ - -void -isc_mem_printactive(isc_mem_t *mctx, FILE *file); -/*%< - * Print to 'file' all active memory in 'mctx'. - * - * Requires ISC_MEM_DEBUGRECORD to have been set. - */ - -void -isc_mem_printallactive(FILE *file); -/*%< - * Print to 'file' all active memory in all contexts. - * - * Requires ISC_MEM_DEBUGRECORD to have been set. - */ - -void -isc_mem_checkdestroyed(FILE *file); -/*%< - * Check that all memory contexts have been destroyed. - * Prints out those that have not been. - * Fatally fails if there are still active contexts. - */ - -/* - * Memory pools - */ - -isc_result_t -isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp); -/*%< - * Create a memory pool. - * - * Requires: - *\li mctx is a valid memory context. - *\li size > 0 - *\li mpctxp != NULL and *mpctxp == NULL - * - * Defaults: - *\li maxalloc = UINT_MAX - *\li freemax = 1 - *\li fillcount = 1 - * - * Returns: - *\li #ISC_R_NOMEMORY -- not enough memory to create pool - *\li #ISC_R_SUCCESS -- all is well. - */ - -void -isc_mempool_destroy(isc_mempool_t **mpctxp); -/*%< - * Destroy a memory pool. - * - * Requires: - *\li mpctxp != NULL && *mpctxp is a valid pool. - *\li The pool has no un"put" allocations outstanding - */ - -void -isc_mempool_setname(isc_mempool_t *mpctx, const char *name); -/*%< - * Associate a name with a memory pool. At most 15 characters may be used. - * - * Requires: - *\li mpctx is a valid pool. - *\li name != NULL; - */ - -/* -void -isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock); -*/ -/*%< - * Associate a lock with this memory pool. - * - * This lock is used when getting or putting items using this memory pool, - * and it is also used to set or get internal state via the isc_mempool_get*() - * and isc_mempool_set*() set of functions. - * - * Mutiple pools can each share a single lock. For instance, if "manager" - * type object contained pools for various sizes of events, and each of - * these pools used a common lock. Note that this lock must NEVER be used - * by other than mempool routines once it is given to a pool, since that can - * easily cause double locking. - * - * Requires: - * - *\li mpctpx is a valid pool. - * - *\li lock != NULL. - * - *\li No previous lock is assigned to this pool. - * - *\li The lock is initialized before calling this function via the normal - * means of doing that. - */ - -/* - * The following functions get/set various parameters. Note that due to - * the unlocked nature of pools these are potentially random values unless - * the imposed externally provided locking protocols are followed. - * - * Also note that the quota limits will not always take immediate effect. - * For instance, setting "maxalloc" to a number smaller than the currently - * allocated count is permitted. New allocations will be refused until - * the count drops below this threshold. - * - * All functions require (in addition to other requirements): - * mpctx is a valid memory pool - */ - -unsigned int -isc_mempool_getfreemax(isc_mempool_t *mpctx); -/*%< - * Returns the maximum allowed size of the free list. - */ - -void -isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit); -/*%< - * Sets the maximum allowed size of the free list. - */ - -unsigned int -isc_mempool_getfreecount(isc_mempool_t *mpctx); -/*%< - * Returns current size of the free list. - */ - -unsigned int -isc_mempool_getmaxalloc(isc_mempool_t *mpctx); -/*!< - * Returns the maximum allowed number of allocations. - */ - -void -isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit); -/*%< - * Sets the maximum allowed number of allocations. - * - * Additional requirements: - *\li limit > 0 - */ - -unsigned int -isc_mempool_getallocated(isc_mempool_t *mpctx); -/*%< - * Returns the number of items allocated from this pool. - */ - -unsigned int -isc_mempool_getfillcount(isc_mempool_t *mpctx); -/*%< - * Returns the number of items allocated as a block from the parent memory - * context when the free list is empty. - */ - -void -isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit); -/*%< - * Sets the fillcount. - * - * Additional requirements: - *\li limit > 0 - */ - - -/* - * Pseudo-private functions for use via macros. Do not call directly. - */ -void * -isc__mem_get(isc_mem_t *, size_t _ISC_MEM_FLARG); -void -isc__mem_putanddetach(isc_mem_t **, void *, - size_t _ISC_MEM_FLARG); -void -isc__mem_put(isc_mem_t *, void *, size_t _ISC_MEM_FLARG); -void * -isc__mem_allocate(isc_mem_t *, size_t _ISC_MEM_FLARG); -void -isc__mem_free(isc_mem_t *, void * _ISC_MEM_FLARG); -char * -isc__mem_strdup(isc_mem_t *, const char *_ISC_MEM_FLARG); -void * -isc__mempool_get(isc_mempool_t * _ISC_MEM_FLARG); -void -isc__mempool_put(isc_mempool_t *, void * _ISC_MEM_FLARG); - -#ifdef HAVE_LIBXML2 -void -isc_mem_renderxml(isc_mem_t *mgr, xmlTextWriterPtr writer); -#endif /* HAVE_LIBXML2 */ - -ISC_LANG_ENDDECLS - -#endif /* ISC_MEM_H */ diff --git a/includes/isc-dhcp/print.h b/includes/isc-dhcp/print.h deleted file mode 100644 index 856e0f88..00000000 --- a/includes/isc-dhcp/print.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001, 2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and/or 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: print.h,v 1.2 2007/11/16 11:04:11 shane Exp $ */ - -#ifndef ISC_PRINT_H -#define ISC_PRINT_H 1 - -/*! \file isc/print.h */ - -/*** - *** Imports - ***/ - -#include /* Required for ISC_FORMAT_PRINTF() macro. */ -#include -/*#include */ - -/*! - * This block allows lib/isc/print.c to be cleanly compiled even if - * the platform does not need it. The standard Makefile will still - * not compile print.c or archive print.o, so this is just to make test - * compilation ("make print.o") easier. - */ -#if !defined(ISC_PLATFORM_NEEDVSNPRINTF) && defined(ISC__PRINT_SOURCE) -#define ISC_PLATFORM_NEEDVSNPRINTF -#endif - -#if !defined(ISC_PLATFORM_NEEDSPRINTF) && defined(ISC__PRINT_SOURCE) -#define ISC_PLATFORM_NEEDSPRINTF -#endif - -/*** - *** Macros - ***/ -#define ISC_PRINT_QUADFORMAT ISC_PLATFORM_QUADFORMAT - -/*** - *** Functions - ***/ - -#ifdef ISC_PLATFORM_NEEDVSNPRINTF -#include -#include -#endif -#ifdef ISC_PLATFORM_NEEDSPRINTF -#include -#endif - - -ISC_LANG_BEGINDECLS - -#ifdef ISC_PLATFORM_NEEDVSNPRINTF -int -isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) - ISC_FORMAT_PRINTF(3, 0); -#define vsnprintf isc_print_vsnprintf - -int -isc_print_snprintf(char *str, size_t size, const char *format, ...) - ISC_FORMAT_PRINTF(3, 4); -#define snprintf isc_print_snprintf -#endif /* ISC_PLATFORM_NEEDVSNPRINTF */ - -#ifdef ISC_PLATFORM_NEEDSPRINTF -int -isc_print_sprintf(char *str, const char *format, ...) ISC_FORMAT_PRINTF(2, 3); -#define sprintf isc_print_sprintf -#endif - -ISC_LANG_ENDDECLS - -#endif /* ISC_PRINT_H */ diff --git a/includes/isc-dhcp/result.h b/includes/isc-dhcp/result.h deleted file mode 100644 index 2f7daac4..00000000 --- a/includes/isc-dhcp/result.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1998-2003 by 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. - * - * Internet Systems Consortium, Inc. - * 950 Charter Street - * Redwood City, CA 94063 - * - * https://www.isc.org/ - */ - -#ifndef ISC_RESULT_H -#define ISC_RESULT_H 1 - -#include -#include -#include -#include - -ISC_LANG_BEGINDECLS - -typedef enum { - ISC_R_SUCCESS = 0, - ISC_R_NOMEMORY = 1, - ISC_R_TIMEDOUT = 2, - ISC_R_NOTHREADS = 3, - ISC_R_ADDRNOTAVAIL = 4, - ISC_R_ADDRINUSE = 5, - ISC_R_NOPERM = 6, - ISC_R_NOCONN = 7, - ISC_R_NETUNREACH = 8, - ISC_R_HOSTUNREACH = 9, - ISC_R_NETDOWN = 10, - ISC_R_HOSTDOWN = 11, - ISC_R_CONNREFUSED = 12, - ISC_R_NORESOURCES = 13, - ISC_R_EOF = 14, - ISC_R_BOUND = 15, - ISC_R_TASKDONE = 16, - ISC_R_LOCKBUSY = 17, - ISC_R_EXISTS = 18, - ISC_R_NOSPACE = 19, - ISC_R_CANCELED = 20, - ISC_R_TASKNOSEND = 21, - ISC_R_SHUTTINGDOWN = 22, - ISC_R_NOTFOUND = 23, - ISC_R_UNEXPECTEDEND = 24, - ISC_R_FAILURE = 25, - ISC_R_IOERROR = 26, - ISC_R_NOTIMPLEMENTED = 27, - ISC_R_UNBALANCED = 28, - ISC_R_NOMORE = 29, - ISC_R_INVALIDFILE = 30, - ISC_R_BADBASE64 = 31, - ISC_R_UNEXPECTEDTOKEN = 32, - ISC_R_QUOTA = 33, - ISC_R_UNEXPECTED = 34, - ISC_R_ALREADYRUNNING = 35, - ISC_R_HOSTUNKNOWN = 36, - ISC_R_VERSIONMISMATCH = 37, - ISC_R_PROTOCOLERROR = 38, - ISC_R_INVALIDARG = 39, - ISC_R_NOTCONNECTED = 40, - ISC_R_NOTYET = 41, - ISC_R_UNCHANGED = 42, - ISC_R_MULTIPLE = 43, - ISC_R_KEYCONFLICT = 44, - ISC_R_BADPARSE = 45, - ISC_R_NOKEYS = 46, - ISC_R_KEY_UNKNOWN = 47, - ISC_R_INVALIDKEY = 48, - ISC_R_INCOMPLETE = 49, - ISC_R_FORMERR = 50, - ISC_R_SERVFAIL = 51, - ISC_R_NXDOMAIN = 52, - ISC_R_NOTIMPL = 53, - ISC_R_REFUSED = 54, - ISC_R_YXDOMAIN = 55, - ISC_R_YXRRSET = 56, - ISC_R_NXRRSET = 57, - ISC_R_NOTAUTH = 58, - ISC_R_NOTZONE = 59, - ISC_R_BADSIG = 60, - ISC_R_BADKEY = 61, - ISC_R_BADTIME = 62, - ISC_R_NOROOTZONE = 63, - ISC_R_DESTADDRREQ = 64, - ISC_R_CROSSZONE = 65, - ISC_R_NO_TSIG = 66, - ISC_R_NOT_EQUAL = 67, - ISC_R_CONNRESET = 68, - ISC_R_UNKNOWNATTRIBUTE = 69 -} isc_result_t; - - -#define ISC_R_NRESULTS 70 /* Number of results */ - -const char * isc_result_totext(isc_result_t); -isc_result_t isc_result_register(unsigned int base, - unsigned int nresults, - char **text, - isc_msgcat_t *msgcat, - int set); - -ISC_LANG_ENDDECLS - -#endif /* ISC_RESULT_H */ diff --git a/includes/isc-dhcp/string.h b/includes/isc-dhcp/string.h deleted file mode 100644 index 543b6a61..00000000 --- a/includes/isc-dhcp/string.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and/or 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: string.h,v 1.2 2007/11/16 11:04:11 shane Exp $ */ - -#ifndef ISC_STRING_H -#define ISC_STRING_H 1 - -/*! \file isc/string.h */ - -#include -#include -#include -/*#include */ -#include -#include - -#include - -#ifdef ISC_PLATFORM_HAVESTRINGSH -#include -#endif - -#define ISC_STRING_MAGIC 0x5e - -ISC_LANG_BEGINDECLS - -isc_uint64_t -isc_string_touint64(char *source, char **endp, int base); -/*%< - * Convert the string pointed to by 'source' to isc_uint64_t. - * - * On successful conversion 'endp' points to the first character - * after conversion is complete. - * - * 'base': 0 or 2..36 - * - * If base is 0 the base is computed from the string type. - * - * On error 'endp' points to 'source'. - */ - -isc_result_t -isc_string_copy(char *target, size_t size, const char *source); -/* - * Copy the string pointed to by 'source' to 'target' which is a - * pointer to a string of at least 'size' bytes. - * - * Requires: - * 'target' is a pointer to a char[] of at least 'size' bytes. - * 'size' an integer > 0. - * 'source' == NULL or points to a NUL terminated string. - * - * Ensures: - * If result == ISC_R_SUCCESS - * 'target' will be a NUL terminated string of no more - * than 'size' bytes (including NUL). - * - * If result == ISC_R_NOSPACE - * 'target' is undefined. - * - * Returns: - * ISC_R_SUCCESS -- 'source' was successfully copied to 'target'. - * ISC_R_NOSPACE -- 'source' could not be copied since 'target' - * is too small. - */ - -void -isc_string_copy_truncate(char *target, size_t size, const char *source); -/* - * Copy the string pointed to by 'source' to 'target' which is a - * pointer to a string of at least 'size' bytes. - * - * Requires: - * 'target' is a pointer to a char[] of at least 'size' bytes. - * 'size' an integer > 0. - * 'source' == NULL or points to a NUL terminated string. - * - * Ensures: - * 'target' will be a NUL terminated string of no more - * than 'size' bytes (including NUL). - */ - -isc_result_t -isc_string_append(char *target, size_t size, const char *source); -/* - * Append the string pointed to by 'source' to 'target' which is a - * pointer to a NUL terminated string of at least 'size' bytes. - * - * Requires: - * 'target' is a pointer to a NUL terminated char[] of at - * least 'size' bytes. - * 'size' an integer > 0. - * 'source' == NULL or points to a NUL terminated string. - * - * Ensures: - * If result == ISC_R_SUCCESS - * 'target' will be a NUL terminated string of no more - * than 'size' bytes (including NUL). - * - * If result == ISC_R_NOSPACE - * 'target' is undefined. - * - * Returns: - * ISC_R_SUCCESS -- 'source' was successfully appended to 'target'. - * ISC_R_NOSPACE -- 'source' could not be appended since 'target' - * is too small. - */ - -void -isc_string_append_truncate(char *target, size_t size, const char *source); -/* - * Append the string pointed to by 'source' to 'target' which is a - * pointer to a NUL terminated string of at least 'size' bytes. - * - * Requires: - * 'target' is a pointer to a NUL terminated char[] of at - * least 'size' bytes. - * 'size' an integer > 0. - * 'source' == NULL or points to a NUL terminated string. - * - * Ensures: - * 'target' will be a NUL terminated string of no more - * than 'size' bytes (including NUL). - */ - -isc_result_t -isc_string_printf(char *target, size_t size, const char *format, ...) - ISC_FORMAT_PRINTF(3, 4); -/* - * Print 'format' to 'target' which is a pointer to a string of at least - * 'size' bytes. - * - * Requires: - * 'target' is a pointer to a char[] of at least 'size' bytes. - * 'size' an integer > 0. - * 'format' == NULL or points to a NUL terminated string. - * - * Ensures: - * If result == ISC_R_SUCCESS - * 'target' will be a NUL terminated string of no more - * than 'size' bytes (including NUL). - * - * If result == ISC_R_NOSPACE - * 'target' is undefined. - * - * Returns: - * ISC_R_SUCCESS -- 'format' was successfully printed to 'target'. - * ISC_R_NOSPACE -- 'format' could not be printed to 'target' since it - * is too small. - */ - -void -isc_string_printf_truncate(char *target, size_t size, const char *format, ...) - ISC_FORMAT_PRINTF(3, 4); -/* - * Print 'format' to 'target' which is a pointer to a string of at least - * 'size' bytes. - * - * Requires: - * 'target' is a pointer to a char[] of at least 'size' bytes. - * 'size' an integer > 0. - * 'format' == NULL or points to a NUL terminated string. - * - * Ensures: - * 'target' will be a NUL terminated string of no more - * than 'size' bytes (including NUL). - */ - - -/* -char * -isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source); -*/ -/* - * Copy the region pointed to by r to a NUL terminated string - * allocated from the memory context pointed to by mctx. - * - * The result should be deallocated using isc_mem_free() - * - * Requires: - * 'mctx' is a point to a valid memory context. - * 'source' is a pointer to a valid region. - * - * Returns: - * a pointer to a NUL terminated string or - * NULL if memory for the copy could not be allocated - * - */ - -char * -isc_string_separate(char **stringp, const char *delim); - -#ifdef ISC_PLATFORM_NEEDSTRSEP -#define strsep isc_string_separate -#endif - -#ifdef ISC_PLATFORM_NEEDMEMMOVE -#define memmove(a,b,c) bcopy(b,a,c) -#endif - -size_t -isc_string_strlcpy(char *dst, const char *src, size_t size); - - -#ifdef ISC_PLATFORM_NEEDSTRLCPY -#define strlcpy isc_string_strlcpy -#endif - - -size_t -isc_string_strlcat(char *dst, const char *src, size_t size); - -#ifdef ISC_PLATFORM_NEEDSTRLCAT -#define strlcat isc_string_strlcat -#endif - -ISC_LANG_ENDDECLS - -#endif /* ISC_STRING_H */ diff --git a/includes/isc-dhcp/types.h b/includes/isc-dhcp/types.h deleted file mode 100644 index 9bdc2e86..00000000 --- a/includes/isc-dhcp/types.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1999-2003 by 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. - * - * Internet Systems Consortium, Inc. - * 950 Charter Street - * Redwood City, CA 94063 - * - * https://www.isc.org/ - */ - -#ifndef ISC_TYPES_H -#define ISC_TYPES_H 1 - -#include -#include -#include - -/*** - *** Core Types. - ***/ - -typedef struct isc_mem isc_mem_t; -typedef struct isc_mempool isc_mempool_t; -typedef struct isc_msgcat isc_msgcat_t; -typedef unsigned int isc_eventtype_t; -typedef struct isc_event isc_event_t; -typedef struct isc_task isc_task_t; -typedef struct isc_taskmgr isc_taskmgr_t; -typedef struct isc_rwlock isc_rwlock_t; - -typedef void (*isc_taskaction_t)(isc_task_t *, isc_event_t *); - -#endif /* ISC_TYPES_H */ diff --git a/includes/isc-dhcp/boolean.h b/includes/minires.h similarity index 50% rename from includes/isc-dhcp/boolean.h rename to includes/minires.h index 18683215..3555bbb0 100644 --- a/includes/isc-dhcp/boolean.h +++ b/includes/minires.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1998-2003 by Internet Software Consortium + * Copyright (c) 2004,2007-2009 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2001-2003 by 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 @@ -18,21 +18,26 @@ * 950 Charter Street * Redwood City, CA 94063 * - * https://www.isc.org/ + * http://www.isc.org/ + */ +#ifndef MINIRES_H +#define MINIRES_H + +#include "cdefs.h" +#include "osdep.h" + +/* + * Based on the Dynamic DNS reference implementation by Viraj Bais + * */ -#ifndef ISC_BOOLEAN_H -#define ISC_BOOLEAN_H 1 +int MRns_name_compress(const char *, u_char *, size_t, const unsigned char **, + const unsigned char **); +int MRns_name_unpack(const unsigned char *, const unsigned char *, + const unsigned char *, unsigned char *, size_t); +int MRns_name_pack (const unsigned char *, unsigned char *, + unsigned, const unsigned char **, const unsigned char **); +int MRns_name_ntop(const unsigned char *, char *, size_t); +int MRns_name_pton(const char *, u_char *, size_t); -#include - -ISC_LANG_BEGINDECLS - -typedef enum { isc_boolean_false = 0, isc_boolean_true = 1 } isc_boolean_t; - -#define ISC_FALSE isc_boolean_false -#define ISC_TRUE isc_boolean_true - -ISC_LANG_ENDDECLS - -#endif /* ISC_BOOLEAN_H */ +#endif /* MINIRES_H */ diff --git a/includes/minires/minires.h b/includes/minires/minires.h deleted file mode 100644 index 0bea1644..00000000 --- a/includes/minires/minires.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2004,2007-2008 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 2001-2003 by 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. - * - * Internet Systems Consortium, Inc. - * 950 Charter Street - * Redwood City, CA 94063 - * - * https://www.isc.org/ - */ -#ifndef MINIRES_H -#define MINIRES_H - -#include "cdefs.h" -#include "osdep.h" - -#define _ns_flagdata MR_ns_flagdata - -#include "minires/resolv.h" -#include "minires/res_update.h" -#include "isc-dhcp/result.h" - -/* - * Based on the Dynamic DNS reference implementation by Viraj Bais - * - */ - -int minires_mkupdate (ns_updrec *, unsigned char *, unsigned); -int minires_update (ns_updrec *); -ns_updrec *minires_mkupdrec (int, const char *, unsigned int, - unsigned int, unsigned long); -void minires_freeupdrec (ns_updrec *); -int minires_nmkupdate (res_state, ns_updrec *, double *, unsigned *); -isc_result_t minires_nupdate (res_state, ns_updrec *); -int minires_ninit (res_state); -ns_rcode isc_rcode_to_ns (isc_result_t); - -int MRns_name_compress(const char *, u_char *, size_t, const unsigned char **, - const unsigned char **); -int MRns_name_unpack(const unsigned char *, const unsigned char *, - const unsigned char *, unsigned char *, size_t); -int MRns_name_ntop(const unsigned char *, char *, size_t); -int MRns_name_pton(const char *, u_char *, size_t); - -#if defined (MINIRES_LIB) -#define res_update minires_update -#define res_mkupdate minires_mkupdate -#define res_mkupdrec minires_mkupdrec -#define res_freeupdrec minires_freeupdrec -#define res_nmkupdate minires_nmkupdate -#define res_nupdate minires_nupdate -#define __p_type_syms MR__p_type_syms -#define dn_comp MRdn_comp -#define loc_aton MRloc_aton -#define sym_ston MRsym_ston -#define res_buildservicelist MRres_buildservicelist -#define res_destroyservicelist MRres_destroyservicelist -#define res_buildprotolist MRres_buildprotolist -#define res_destroyprotolist MRres_destroyprotolist -#define res_servicenumber MRres_servicenumber -#define res_protocolnumber MRres_protocolnumber -#define res_protocolname MRres_protocolname -#define res_servicename MRres_servicename -#define ns_datetosecs MRns_datetosecs -#define b64_pton MRb64_pton -#define res_ninit minires_ninit -#define res_randomid MRres_randomid -#define res_findzonecut MRres_findzonecut -#define res_nsend MRres_nsend -#define res_nsendsigned MRres_nsendsigned -#define ns_samename MRns_samename -#define res_nameinquery MRres_nameinquery -#define res_queriesmatch MRres_queriesmatch -#define dn_expand MRdn_expand -#define ns_get16 MRns_get16 -#define res_close MRres_close -#define res_nclose MRres_nclose -#define res_ourserver_p MRres_ourserver_p -#define ns_sign MRns_sign -#define p_class MRp_class -#define p_section MRp_section -#define ns_makecanon MRns_makecanon -#define ns_parserr MRns_parserr -#define ns_samedomain MRns_samedomain -#define ns_name_uncompress MRns_name_uncompress -#define res_nmkquery MRres_nmkquery -#define ns_initparse MRns_initparse -#define res_nquery MRres_nquery -#define res_nsearch MRres_nsearch -#define res_hostalias MRres_hostalias -#define res_nquerydomain MRres_nquerydomain -#define ns_skiprr MRns_skiprr -#define dn_skipname MRdn_skipname -#define ns_name_ntol MRns_name_ntol -#define ns_sign_tcp_init MRns_sign_tcp_init -#define ns_sign_tcp MRns_sign_tcp -#define ns_name_ntop MRns_name_ntop -#define ns_name_pton MRns_name_pton -#define ns_name_unpack MRns_name_unpack -#define ns_name_pack MRns_name_pack -#define ns_name_compress MRns_name_compress -#define ns_name_skip MRns_name_skip -#define ns_subdomain MRns_subdomain -#define ns_find_tsig MRns_find_tsig -#define ns_verify MRns_verify -#define ns_verify_tcp_init MRns_verify_tcp_init -#define ns_verify_tcp MRns_verify_tcp -#define b64_ntop MRb64_ntop - -extern const struct res_sym __p_type_syms[]; -extern struct timeval cur_tv; -#define cur_time cur_tv.tv_sec - -int dn_comp (const char *, - unsigned char *, unsigned, unsigned char **, unsigned char **); -int loc_aton (const char *, u_char *); -int sym_ston (const struct res_sym *, const char *, int *); -void res_buildservicelist (void); -void res_destroyservicelist (void); -void res_buildprotolist(void); -void res_destroyprotolist(void); -const char *res_protocolname(int); -const char *res_servicename(u_int16_t, const char *); -u_int32_t ns_datetosecs (const char *cp, int *errp); -int b64_pton (char const *, unsigned char *, size_t); -u_int res_randomid(void); -isc_result_t res_findzonecut (res_state, const char *, ns_class, int, char *, - size_t, struct in_addr *, int, int *, void *); -isc_result_t res_nsend (res_state, - double *, unsigned, double *, unsigned, unsigned *); -isc_result_t res_nsendsigned (res_state, double *, unsigned, ns_tsig_key *, - double *, unsigned, unsigned *); -int ns_samename (const char *, const char *); -int res_nameinquery (const char *, int, int, - const unsigned char *, const unsigned char *); -int res_queriesmatch (const unsigned char *, const unsigned char *, - const unsigned char *, const unsigned char *); -int dn_expand (const unsigned char *, - const unsigned char *, const unsigned char *, char *, unsigned); -unsigned int ns_get16 (const unsigned char *); -void res_close (void); -void res_nclose (res_state); -int res_ourserver_p (const res_state, const struct sockaddr_in *); -isc_result_t ns_sign (unsigned char *, unsigned *, - unsigned, int, void *, const unsigned char *, - unsigned, unsigned char *, unsigned *, time_t); -const char *p_class (int); -const char *p_section (int section, int opcode); -isc_result_t ns_makecanon (const char *, char *, size_t); -isc_result_t ns_parserr (ns_msg *, ns_sect, int, ns_rr *); -int ns_samedomain (const char *, const char *); -int ns_name_uncompress (const u_char *, const u_char *, - const u_char *, char *, size_t); -isc_result_t res_nmkquery (res_state, int, const char *, ns_class, ns_type, - const unsigned char *, unsigned, - const unsigned char *, double *, - unsigned, unsigned *); -isc_result_t ns_initparse (const unsigned char *, unsigned, ns_msg *); -isc_result_t res_nquery(res_state, const char *, - ns_class, ns_type, double *, unsigned, unsigned *); -isc_result_t res_nsearch(res_state, const char *, - ns_class, ns_type, double *, unsigned, unsigned *); -const char *res_hostalias (const res_state, const char *, char *, size_t); -isc_result_t res_nquerydomain(res_state, const char *, const char *, - ns_class class, ns_type type, - double *, unsigned, unsigned *); - -isc_result_t ns_skiprr(const unsigned char *, - const unsigned char *, ns_sect, int, int *); -int dn_skipname (const unsigned char *, const unsigned char *); -u_int32_t getULong (const unsigned char *); -int32_t getLong (const unsigned char *); -u_int32_t getUShort (const unsigned char *); -int32_t getShort (const unsigned char *); -u_int32_t getUChar (const unsigned char *); -void putULong (unsigned char *, u_int32_t); -void putLong (unsigned char *, int32_t); -void putUShort (unsigned char *, u_int32_t); -void putShort (unsigned char *, int32_t); -void putUChar (unsigned char *, u_int32_t); -int ns_name_ntol (const unsigned char *, unsigned char *, size_t); -isc_result_t ns_sign_tcp_init (void *, const unsigned char *, - unsigned, ns_tcp_tsig_state *); -isc_result_t ns_sign_tcp (unsigned char *, - unsigned *, unsigned, int, ns_tcp_tsig_state *, int); -int ns_name_pack (const unsigned char *, unsigned char *, - unsigned, const unsigned char **, const unsigned char **); -int ns_name_skip (const unsigned char **, const unsigned char *); -int ns_subdomain (const char *, const char *); -unsigned char *ns_find_tsig (unsigned char *, unsigned char *); -isc_result_t ns_verify (unsigned char *, unsigned *, void *, - const unsigned char *, - unsigned, unsigned char *, unsigned *, time_t *, int); -isc_result_t ns_verify_tcp_init (void *, const unsigned char *, unsigned, - ns_tcp_tsig_state *); -isc_result_t ns_verify_tcp (unsigned char *, unsigned *, - ns_tcp_tsig_state *, int); -int b64_ntop (unsigned char const *, size_t, char *, size_t); - -ns_rcode find_cached_zone (const char *, ns_class, char *, - size_t, struct in_addr *, int, int *, void *); -int find_tsig_key (ns_tsig_key **, const char *, void *); -int forget_zone (void *); -int repudiate_zone (void *); -void cache_found_zone (ns_class, char *, struct in_addr *, int); -isc_result_t uerr2isc (int); -isc_result_t ns_rcode_to_isc (int); - -#define DprintQ(a,b,c,d) -#define Dprint(a,b) -#define Perror(a, b, c, d) -#define Aerror(a, b, c, d, e) -#define DPRINTF(x) - -#define USE_MD5 -#endif - -#if defined (TRACING) -void trace_mr_statp_setup (res_state); -#endif - -#endif /* MINIRES_H */ diff --git a/includes/minires/res_update.h b/includes/minires/res_update.h deleted file mode 100644 index 991fa549..00000000 --- a/includes/minires/res_update.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1999-2003 by 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. - * - * Internet Systems Consortium, Inc. - * 950 Charter Street - * Redwood City, CA 94063 - * - * https://www.isc.org/ - */ - -/* - * $Id: res_update.h,v 1.5 2009/07/23 18:52:20 sar Exp $ - */ - -#ifndef __RES_UPDATE_H -#define __RES_UPDATE_H - -#include -#include "arpa/nameser.h" -#include - -/* - * This RR-like structure is particular to UPDATE. - */ -typedef struct ns_updrec { - ISC_LINK(struct ns_updrec) r_link, r_glink; - ns_sect r_section; /* ZONE/PREREQUISITE/UPDATE */ - char *r_dname; /* owner of the RR */ - ns_class r_class; /* class number */ - ns_type r_type; /* type number */ - u_int32_t r_ttl; /* time to live */ - const unsigned char *r_data; /* rdata fields as text string */ - unsigned char *r_data_ephem; /* pointer to freeable r_data */ - unsigned int r_size; /* size of r_data field */ - int r_opcode; /* type of operation */ - /* following fields for private use by the resolver/server - routines */ - struct databuf *r_dp; /* databuf to process */ - struct databuf *r_deldp; /* databuf's deleted/overwritten */ - unsigned int r_zone; /* zone number on server */ -} ns_updrec; -typedef ISC_LIST(ns_updrec) ns_updque; - -#endif /*__RES_UPDATE_H*/ diff --git a/includes/minires/resolv.h b/includes/minires/resolv.h deleted file mode 100644 index 5cce3845..00000000 --- a/includes/minires/resolv.h +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (c) 1983, 1987, 1989 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 2004,2007-2008 by Internet Systems Consortium, - * Inc. ("ISC") - * Portions Copyright (c) 1995-2003 by 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. - * - * Internet Systems Consortium, Inc. - * 950 Charter Street - * Redwood City, CA 94063 - * - * https://www.isc.org/ - */ - -/* - * @(#)resolv.h 8.1 (Berkeley) 6/2/93 - * $Id: resolv.h,v 1.7 2009/07/23 18:52:20 sar Exp $ - */ - -#ifndef _RESOLV_H_ -#define _RESOLV_H_ - -#include - -/* - * This used to be defined in res_query.c, now it's in herror.c. - * [XXX no it's not. It's in irs/irs_data.c] - * It was - * never extern'd by any *.h file before it was placed here. For thread - * aware programs, the last h_errno value set is stored in res->h_errno. - * - * XXX: There doesn't seem to be a good reason for exposing RES_SET_H_ERRNO - * (and __h_errno_set) to the public via . - * XXX: __h_errno_set is really part of IRS, not part of the resolver. - * If somebody wants to build and use a resolver that doesn't use IRS, - * what do they do? Perhaps something like - * #ifdef WANT_IRS - * # define RES_SET_H_ERRNO(r,x) __h_errno_set(r,x) - * #else - * # define RES_SET_H_ERRNO(r,x) (h_errno = (r)->res_h_errno = (x)) - * #endif - */ - -#define RES_SET_H_ERRNO(r,x) __h_errno_set(r,x) -struct __res_state; /* forward */ -void __h_errno_set(struct __res_state *res, int err); - -/* - * Resolver configuration file. - * Normally not present, but may contain the address of the - * inital name server(s) to query and the domain search list. - */ - -#ifndef _PATH_RESCONF -#define _PATH_RESCONF "/etc/resolv.conf" -#endif - -typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error } - res_sendhookact; - -typedef res_sendhookact (*res_send_qhook) (struct sockaddr_in * const *ns, - double **query, - unsigned *querylen, - double *ans, - unsigned anssiz, - int *resplen); - -typedef res_sendhookact (*res_send_rhook) (const struct sockaddr_in *ns, - double *query, - unsigned querylen, - double *ans, - unsigned anssiz, - int *resplen); - -struct res_sym { - int number; /* Identifying number, like T_MX */ - char * name; /* Its symbolic name, like "MX" */ - char * humanname; /* Its fun name, like "mail exchanger" */ -}; - -/* - * Global defines and variables for resolver stub. - */ -#define MAXNS 3 /* max # name servers we'll track */ -#define MAXDFLSRCH 3 /* # default domain levels to try */ -#define MAXDNSRCH 6 /* max # domains in search path */ -#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */ - -#define RES_TIMEOUT 5 /* min. seconds between retries */ -#define MAXRESOLVSORT 10 /* number of net to sort on */ -#define RES_MAXNDOTS 15 /* should reflect bit field size */ -#define RES_MAXRETRANS 30 /* only for resolv.conf/RES_OPTIONS */ -#define RES_MAXRETRY 5 /* only for resolv.conf/RES_OPTIONS */ -#define RES_DFLRETRY 2 /* Default #/tries. */ - -struct __res_state { - int retrans; /* retransmition time interval */ - int retry; /* number of times to retransmit */ - u_long options; /* option flags - see below. */ - int nscount; /* number of name servers */ - struct sockaddr_in - nsaddr_list[MAXNS]; /* address of name server */ -#define nsaddr nsaddr_list[0] /* for backward compatibility */ - u_short id; /* current message id */ - char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */ - char defdname[256]; /* default domain (deprecated) */ - u_long pfcode; /* RES_PRF_ flags - see below. */ - unsigned ndots:4; /* threshold for initial abs. query */ - unsigned nsort:4; /* number of elements in sort_list[] */ - char unused[3]; - struct { - struct in_addr addr; - u_int32_t mask; - } sort_list[MAXRESOLVSORT]; - res_send_qhook qhook; /* query hook */ - res_send_rhook rhook; /* response hook */ - int res_h_errno; /* last one set for this context */ - int _sock; /* PRIVATE: for res_send i/o */ - u_int _flags; /* PRIVATE: see below */ - char pad[52]; /* On an i386 this means 512b total. */ -}; - -typedef struct __res_state *res_state; - -/* - * Resolver flags (used to be discrete per-module statics ints). - */ -#define RES_F_VC 0x00000001 /* socket is TCP */ -#define RES_F_CONN 0x00000002 /* socket is connected */ - -/* res_findzonecut() options */ -#define RES_EXHAUSTIVE 0x00000001 /* always do all queries */ - -/* - * Resolver options (keep these in synch with res_debug.c, please) - */ -#define RES_INIT 0x00000001 /* address initialized */ -#define RES_DEBUG 0x00000002 /* print debug messages */ -#define RES_AAONLY 0x00000004 /* authoritative answers only (!IMPL)*/ -#define RES_USEVC 0x00000008 /* use virtual circuit */ -#define RES_PRIMARY 0x00000010 /* query primary server only (!IMPL) */ -#define RES_IGNTC 0x00000020 /* ignore trucation errors */ -#define RES_RECURSE 0x00000040 /* recursion desired */ -#define RES_DEFNAMES 0x00000080 /* use default domain name */ -#define RES_STAYOPEN 0x00000100 /* Keep TCP socket open */ -#define RES_DNSRCH 0x00000200 /* search up local domain tree */ -#define RES_INSECURE1 0x00000400 /* type 1 security disabled */ -#define RES_INSECURE2 0x00000800 /* type 2 security disabled */ -#define RES_NOALIASES 0x00001000 /* shuts off HOSTALIASES feature */ -#define RES_USE_INET6 0x00002000 /* use/map IPv6 in gethostbyname() */ -#define RES_ROTATE 0x00004000 /* rotate ns list after each query */ -#define RES_NOCHECKNAME 0x00008000 /* do not check names for sanity. */ -#define RES_KEEPTSIG 0x00010000 /* do not strip TSIG records */ - -#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH) - -/* - * Resolver "pfcode" values. Used by dig. - */ -#define RES_PRF_STATS 0x00000001 -#define RES_PRF_UPDATE 0x00000002 -#define RES_PRF_CLASS 0x00000004 -#define RES_PRF_CMD 0x00000008 -#define RES_PRF_QUES 0x00000010 -#define RES_PRF_ANS 0x00000020 -#define RES_PRF_AUTH 0x00000040 -#define RES_PRF_ADD 0x00000080 -#define RES_PRF_HEAD1 0x00000100 -#define RES_PRF_HEAD2 0x00000200 -#define RES_PRF_TTLID 0x00000400 -#define RES_PRF_HEADX 0x00000800 -#define RES_PRF_QUERY 0x00001000 -#define RES_PRF_REPLY 0x00002000 -#define RES_PRF_INIT 0x00004000 -/* 0x00008000 */ - -#if 0 -/* Things involving an internal (static) resolver context. */ -#ifdef _REENTRANT -extern struct __res_state *__res_state(void); -#define _res (*__res_state()) -#else -#ifndef __BIND_NOSTATIC -extern struct __res_state _res; -#endif -#endif - -void fp_nquery (const u_char *, int, FILE *); -void fp_query (const u_char *, FILE *); -const char * hostalias (const char *); -void p_query (const u_char *); -void res_close (void); -int res_init (void); -int res_isourserver (const struct sockaddr_in *); -int res_mkquery (int, const char *, int, int, const u_char *, - int, const u_char *, u_char *, int); -int res_query (const char *, int, int, u_char *, int); -int res_querydomain (const char *, const char *, int, int, - u_char *, int); -int res_search (const char *, int, int, u_char *, int); -int res_send (const u_char *, int, u_char *, int); -int res_sendsigned (const u_char *, int, ns_tsig_key *, - u_char *, int); - -#if !defined(SHARED_LIBBIND) || defined(LIB) -/* - * If libbind is a shared object (well, DLL anyway) - * these externs break the linker when resolv.h is - * included by a lib client (like named) - * Make them go away if a client is including this - * - */ -extern const struct res_sym __p_key_syms[]; -extern const struct res_sym __p_cert_syms[]; -extern const struct res_sym __p_class_syms[]; -extern const struct res_sym __p_type_syms[]; -extern const struct res_sym __p_rcode_syms[]; -#endif /* SHARED_LIBBIND */ - -int res_hnok (const char *); -int res_ownok (const char *); -int res_mailok (const char *); -int res_dnok (const char *); -int sym_ston (const struct res_sym *, const char *, int *); -const char * sym_ntos (const struct res_sym *, int, int *); -const char * sym_ntop (const struct res_sym *, int, int *); -int b64_ntop (u_char const *, size_t, char *, size_t); -int b64_pton (char const *, u_char *, size_t); -int loc_aton (const char *ascii, u_char *binary); -const char * loc_ntoa (const u_char *binary, char *ascii); -int dn_skipname (const u_char *, const u_char *); -void putlong (u_int32_t, u_char *); -void putshort (u_int16_t, u_char *); -const char * p_class (int); -const char * p_time (u_int32_t); -const char * p_type (int); -const char * p_rcode (int); -const u_char * p_cdnname (const u_char *, const u_char *, int, FILE *); -const u_char * p_cdname (const u_char *, const u_char *, FILE *); -const u_char * p_fqnname (const u_char *cp, const u_char *msg, - int, char *, int); -const u_char * p_fqname (const u_char *, const u_char *, FILE *); -const char * p_option (u_long option); -char * p_secstodate (u_long); -int dn_count_labels (const char *); -int dn_expand (const u_char *, const u_char *, const u_char *, - char *, int); -u_int res_randomid (void); -int res_nameinquery (const char *, int, int, - const u_char *, const u_char *); -int res_queriesmatch (const u_char *, const u_char *, - const u_char *, const u_char *); -const char * p_section (int section, int opcode); -/* Things involving a resolver context. */ -int res_ninit (res_state); -int res_nisourserver (const res_state, - const struct sockaddr_in *); -void fp_resstat (const res_state, FILE *); -void res_npquery (const res_state, const u_char *, int, FILE *); -const char * res_hostalias (const res_state, const char *, - char *, size_t); -int res_nquery (res_state, - const char *, int, int, u_char *, int); -int res_nsearch (res_state, const char *, int, - int, u_char *, int); -int res_nquerydomain (res_state, - const char *, const char *, int, int, - u_char *, int); -int res_nmkquery (res_state, - int, const char *, int, int, const u_char *, - int, const u_char *, u_char *, int); -int res_nsend (res_state, const u_char *, int, u_char *, int); -int res_nsendsigned (res_state, const u_char *, int, - ns_tsig_key *, u_char *, int); -int res_findzonecut (res_state, const char *, ns_class, int, - char *, size_t, struct in_addr *, int); -void res_nclose (res_state); - -#endif /* 0 */ -#endif /* !_RESOLV_H_ */ diff --git a/includes/omapip/isclib.h b/includes/omapip/isclib.h new file mode 100644 index 00000000..ddefeb5f --- /dev/null +++ b/includes/omapip/isclib.h @@ -0,0 +1,122 @@ +/* isclib.h + + connections to the isc and dns libraries */ + +/* + * Copyright (c) 2009 by Internet Systems Consortium, Inc. ("ISC") + * + * 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. + * + * Internet Systems Consortium, Inc. + * 950 Charter Street + * Redwood City, CA 94063 + * + * http://www.isc.org/ + * + */ + +#ifndef ISCLIB_H +#define ISCLIB_H + +#include "config.h" + +#include + +#define MAXWIRE 256 + +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "result.h" + + +/* + * DHCP context structure + * This holds the libisc information for a dhcp entity + */ + +typedef struct dhcp_context { + isc_mem_t *mctx; + isc_appctx_t *actx; + int actx_started; + isc_taskmgr_t *taskmgr; + isc_task_t *task; + isc_socketmgr_t *socketmgr; + isc_timermgr_t *timermgr; +#if defined (NSUPDATE) + dns_client_t *dnsclient; +#endif +} dhcp_context_t; + +extern dhcp_context_t dhcp_gbl_ctx; + +#define DHCP_MAXDNS_WIRE 256 +#define DHCP_MAXNS 3 +#define DHCP_HMAC_MD5_NAME "HMAC-MD5.SIG-ALG.REG.INT." + +isc_result_t dhcp_isc_name(unsigned char *namestr, + dns_fixedname_t *namefix, + dns_name_t **name); + +isc_result_t +isclib_make_dst_key(char *inname, + char *algorithm, + unsigned char *secret, + int length, + dst_key_t **dstkey); + +isc_result_t dhcp_context_create(void); +void isclib_cleanup(void); + +#endif /* ISCLIB_H */ diff --git a/includes/omapip/omapip.h b/includes/omapip/omapip.h index 732c6fe8..012b47f8 100644 --- a/includes/omapip/omapip.h +++ b/includes/omapip/omapip.h @@ -34,9 +34,11 @@ #ifndef _OMAPIP_H_ #define _OMAPIP_H_ -#include +#include "result.h" #include +#include + typedef unsigned int omapi_handle_t; struct __omapi_object; @@ -153,6 +155,7 @@ typedef struct auth_key { char *name; char *algorithm; omapi_data_string_t *key; + dns_tsec_t *tsec_key; } omapi_auth_key_t; #define OMAPI_CREATE 1 diff --git a/includes/omapip/omapip_p.h b/includes/omapip/omapip_p.h index df2c8af7..465f8fd3 100644 --- a/includes/omapip/omapip_p.h +++ b/includes/omapip/omapip_p.h @@ -63,14 +63,21 @@ #include "osdep.h" */ -#include -#include +#include +#include "result.h" #include #include #include #include +/* DST_API control flags */ +/* These are used in functions dst_sign_data and dst_verify_data */ +#define SIG_MODE_INIT 1 /* initalize digest */ +#define SIG_MODE_UPDATE 2 /* add data to digest */ +#define SIG_MODE_FINAL 4 /* generate/verify signature */ +#define SIG_MODE_ALL (SIG_MODE_INIT|SIG_MODE_UPDATE|SIG_MODE_FINAL) + /* OMAPI protocol header, version 1.00 */ typedef struct { u_int32_t authlen; /* Length of authenticator. */ @@ -190,10 +197,10 @@ typedef struct __omapi_connection_object { omapi_buffer_t *outbufs; omapi_listener_object_t *listener; /* Listener that accepted this connection, if any. */ - DST_KEY *in_key; /* Authenticator signing incoming + dst_key_t *in_key; /* Authenticator signing incoming data. */ void *in_context; /* Input hash context. */ - DST_KEY *out_key; /* Authenticator signing outgoing + dst_key_t *out_key; /* Authenticator signing outgoing data. */ void *out_context; /* Output hash context. */ } omapi_connection_object_t; @@ -206,6 +213,7 @@ typedef struct __omapi_io_object { isc_result_t (*reader) (omapi_object_t *); isc_result_t (*writer) (omapi_object_t *); isc_result_t (*reaper) (omapi_object_t *); + isc_socket_t *fd; } omapi_io_object_t; typedef struct __omapi_generic_object { @@ -255,7 +263,7 @@ OMAPI_OBJECT_ALLOC_DECL (omapi_message, omapi_message_object_t, omapi_type_message) isc_result_t omapi_connection_sign_data (int mode, - DST_KEY *key, + dst_key_t *key, void **context, const unsigned char *data, const unsigned len, diff --git a/includes/omapip/result.h b/includes/omapip/result.h new file mode 100644 index 00000000..85534d8a --- /dev/null +++ b/includes/omapip/result.h @@ -0,0 +1,120 @@ +/* result.h + */ + +/* + * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or 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. + * + * Internet Systems Consortium, Inc. + * 950 Charter Street + * Redwood City, CA 94063 + * + * https://www.isc.org/ + */ + +#ifndef DHCP_RESULT_H +#define DHCP_RESULT_H 1 + +#include +#include +#include + +#include + +/* + * DHCP result codes + */ + +/* + * In the previous code the results started at 36 + * rather than ISC_RESULTCLASS_DHCP + 0 + * ISC_R_NOTCONNECTED was + 4 (40), it has been superseded by the isc version + */ + +#define DHCP_R_HOSTUNKNOWN (ISC_RESULTCLASS_DHCP + 0) +#define DHCP_R_VERSIONMISMATCH (ISC_RESULTCLASS_DHCP + 1) +#define DHCP_R_PROTOCOLERROR (ISC_RESULTCLASS_DHCP + 2) +#define DHCP_R_INVALIDARG (ISC_RESULTCLASS_DHCP + 3) +#define DHCP_R_NOTYET (ISC_RESULTCLASS_DHCP + 4) +#define DHCP_R_UNCHANGED (ISC_RESULTCLASS_DHCP + 5) +#define DHCP_R_MULTIPLE (ISC_RESULTCLASS_DHCP + 6) +#define DHCP_R_KEYCONFLICT (ISC_RESULTCLASS_DHCP + 7) +#define DHCP_R_BADPARSE (ISC_RESULTCLASS_DHCP + 8) +#define DHCP_R_NOKEYS (ISC_RESULTCLASS_DHCP + 9) +#define DHCP_R_KEY_UNKNOWN (ISC_RESULTCLASS_DHCP + 10) +#define DHCP_R_INVALIDKEY (ISC_RESULTCLASS_DHCP + 11) +#define DHCP_R_INCOMPLETE (ISC_RESULTCLASS_DHCP + 12) +#define DHCP_R_FORMERR (ISC_RESULTCLASS_DHCP + 13) +#define DHCP_R_SERVFAIL (ISC_RESULTCLASS_DHCP + 14) +#define DHCP_R_NXDOMAIN (ISC_RESULTCLASS_DHCP + 15) +#define DHCP_R_NOTIMPL (ISC_RESULTCLASS_DHCP + 16) +#define DHCP_R_REFUSED (ISC_RESULTCLASS_DHCP + 17) +#define DHCP_R_YXDOMAIN (ISC_RESULTCLASS_DHCP + 18) +#define DHCP_R_YXRRSET (ISC_RESULTCLASS_DHCP + 19) +#define DHCP_R_NXRRSET (ISC_RESULTCLASS_DHCP + 20) +#define DHCP_R_NOTAUTH (ISC_RESULTCLASS_DHCP + 21) +#define DHCP_R_NOTZONE (ISC_RESULTCLASS_DHCP + 22) +#define DHCP_R_BADSIG (ISC_RESULTCLASS_DHCP + 23) +#define DHCP_R_BADKEY (ISC_RESULTCLASS_DHCP + 24) +#define DHCP_R_BADTIME (ISC_RESULTCLASS_DHCP + 25) +#define DHCP_R_NOROOTZONE (ISC_RESULTCLASS_DHCP + 26) +#define DHCP_R_DESTADDRREQ (ISC_RESULTCLASS_DHCP + 27) +#define DHCP_R_CROSSZONE (ISC_RESULTCLASS_DHCP + 28) +#define DHCP_R_NO_TSIG (ISC_RESULTCLASS_DHCP + 29) +#define DHCP_R_NOT_EQUAL (ISC_RESULTCLASS_DHCP + 30) +#define DHCP_R_CONNRESET (ISC_RESULTCLASS_DHCP + 31) +#define DHCP_R_UNKNOWNATTRIBUTE (ISC_RESULTCLASS_DHCP + 32) + +#define DHCP_R_NRESULTS 33 /*%< Number of results */ + +// Included for historical reasons, these should be removed as +// soon as reasonable +#define ISC_R_HOSTUNKNOWN DHCP_R_HOSTUNKNOWN +#define ISC_R_VERSIONMISMATCH DHCP_R_VERSIONMISMATCH +#define ISC_R_PROTOCOLERROR DHCP_R_PROTOCOLERROR +#define ISC_R_INVALIDARG DHCP_R_INVALIDARG +#define ISC_R_NOTYET DHCP_R_NOTYET +#define ISC_R_UNCHANGED DHCP_R_UNCHANGED +#define ISC_R_MULTIPLE DHCP_R_MULTIPLE +#define ISC_R_KEYCONFLICT DHCP_R_KEYCONFLICT +#define ISC_R_BADPARSE DHCP_R_BADPARSE +#define ISC_R_NOKEYS DHCP_R_NOKEYS +#define ISC_R_KEY_UNKNOWN DHCP_R_KEY_UNKNOWN +#define ISC_R_INVALIDKEY DHCP_R_INVALIDKEY +#define ISC_R_INCOMPLETE DHCP_R_INCOMPLETE +#define ISC_R_FORMERR DHCP_R_FORMERR +#define ISC_R_SERVFAIL DHCP_R_SERVFAIL +#define ISC_R_NXDOMAIN DHCP_R_NXDOMAIN +#define ISC_R_NOTIMPL DHCP_R_NOTIMPL +#define ISC_R_REFUSED DHCP_R_REFUSED +#define ISC_R_YXDOMAIN DHCP_R_YXDOMAIN +#define ISC_R_YXRRSET DHCP_R_YXRRSET +#define ISC_R_NXRRSET DHCP_R_NXRRSET +#define ISC_R_NOTAUTH DHCP_R_NOTAUTH +#define ISC_R_NOTZONE DHCP_R_NOTZONE +#define ISC_R_BADSIG DHCP_R_BADSIG +#define ISC_R_BADKEY DHCP_R_BADKEY +#define ISC_R_BADTIME DHCP_R_BADTIME +#define ISC_R_NOROOTZONE DHCP_R_NOROOTZONE +#define ISC_R_DESTADDRREQ DHCP_R_DESTADDRREQ +#define ISC_R_CROSSZONE DHCP_R_CROSSZONE +#define ISC_R_NO_TSIG DHCP_R_NO_TSIG +#define ISC_R_NOT_EQUAL DHCP_R_NOT_EQUAL +#define ISC_R_CONNRESET DHCP_R_CONNRESET +#define ISC_R_UNKNOWNATTRIBUTE DHCP_R_UNKNOWNATTRIBUTE + +isc_result_t +dhcp_result_register(void); + +#endif /* DHCP_RESULT_H */ diff --git a/includes/t_api.h b/includes/t_api.h index 3972d0a0..ba1dd79f 100644 --- a/includes/t_api.h +++ b/includes/t_api.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: t_api.h,v 1.2 2007/11/16 11:04:11 shane Exp $ */ +/* $Id: t_api.h,v 1.3 2009/10/28 04:12:30 sar Exp $ */ #ifndef TESTS_T_API_H #define TESTS_T_API_H 1 @@ -24,9 +24,9 @@ #include -#include -#include -#include +#include +#include +#include /* * diff --git a/includes/tree.h b/includes/tree.h index e7d1b961..528d1907 100644 --- a/includes/tree.h +++ b/includes/tree.h @@ -115,7 +115,7 @@ struct binding_value { struct data_string data; unsigned long intval; int boolean; -#if defined (NSUPDATE) +#if defined (NSUPDATE_OLD) ns_updrec *dns; #endif struct fundef *fundef; diff --git a/omapip/Makefile.am b/omapip/Makefile.am index 6a3c39f0..60aecf7f 100644 --- a/omapip/Makefile.am +++ b/omapip/Makefile.am @@ -4,10 +4,11 @@ noinst_PROGRAMS = svtest libomapi_a_SOURCES = protocol.c buffer.c alloc.c result.c connection.c \ errwarn.c listener.c dispatch.c generic.c support.c \ handle.c message.c convert.c hash.c auth.c inet_addr.c \ - array.c trace.c mrtrace.c toisc.c iscprint.c + array.c trace.c mrtrace.c toisc.c iscprint.c isclib.c + man_MANS = omapi.3 EXTRA_DIST = $(man_MANS) svtest_SOURCES = test.c -svtest_LDADD = libomapi.a ../dst/libdst.a +svtest_LDADD = libomapi.a ../bind/lib/libdns.a ../bind/lib/libisc.a diff --git a/omapip/alloc.c b/omapip/alloc.c index ad7f5f68..bff6fa23 100644 --- a/omapip/alloc.c +++ b/omapip/alloc.c @@ -526,7 +526,7 @@ isc_result_t omapi_object_allocate (omapi_object_t **o, /* Sanity check. */ if (tsize < sizeof (omapi_object_t)) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; foo = dmalloc (tsize, file, line); if (!foo) @@ -561,7 +561,7 @@ isc_result_t omapi_object_reference (omapi_object_t **r, const char *file, int line) { if (!h || !r) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (*r) { #if defined (POINTER_DEBUG) @@ -569,7 +569,7 @@ isc_result_t omapi_object_reference (omapi_object_t **r, file, line); abort (); #else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } *r = h; @@ -588,14 +588,14 @@ isc_result_t omapi_object_dereference (omapi_object_t **h, omapi_object_t *p, *hp; if (!h) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (!*h) { #if defined (POINTER_DEBUG) log_error ("%s(%d): dereference of null pointer!", file, line); abort (); #else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } @@ -609,7 +609,7 @@ isc_result_t omapi_object_dereference (omapi_object_t **h, abort (); #else *h = 0; - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } @@ -727,7 +727,7 @@ isc_result_t omapi_buffer_reference (omapi_buffer_t **r, const char *file, int line) { if (!h || !r) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (*r) { #if defined (POINTER_DEBUG) @@ -735,7 +735,7 @@ isc_result_t omapi_buffer_reference (omapi_buffer_t **r, file, line); abort (); #else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } *r = h; @@ -748,14 +748,14 @@ isc_result_t omapi_buffer_dereference (omapi_buffer_t **h, const char *file, int line) { if (!h) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (!*h) { #if defined (POINTER_DEBUG) log_error ("%s(%d): dereference of null pointer!", file, line); abort (); #else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } @@ -769,7 +769,7 @@ isc_result_t omapi_buffer_dereference (omapi_buffer_t **h, abort (); #else *h = 0; - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } @@ -807,7 +807,7 @@ isc_result_t omapi_typed_data_new (const char *file, int line, len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val; if (len < val) { va_end(l); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } break; case omapi_datatype_data: @@ -815,7 +815,7 @@ isc_result_t omapi_typed_data_new (const char *file, int line, len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val; if (len < val) { va_end(l); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } break; case omapi_datatype_object: @@ -824,7 +824,7 @@ isc_result_t omapi_typed_data_new (const char *file, int line, break; default: va_end (l); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } va_end (l); @@ -863,14 +863,14 @@ isc_result_t omapi_typed_data_reference (omapi_typed_data_t **r, const char *file, int line) { if (!h || !r) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (*r) { #if defined (POINTER_DEBUG) log_error ("%s(%d): reference store into non-null pointer!", file, line); abort (); #else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } *r = h; @@ -883,14 +883,14 @@ isc_result_t omapi_typed_data_dereference (omapi_typed_data_t **h, const char *file, int line) { if (!h) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (!*h) { #if defined (POINTER_DEBUG) log_error ("%s(%d): dereference of null pointer!", file, line); abort (); #else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } @@ -904,7 +904,7 @@ isc_result_t omapi_typed_data_dereference (omapi_typed_data_t **h, abort (); #else *h = 0; - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } @@ -936,7 +936,7 @@ isc_result_t omapi_data_string_new (omapi_data_string_t **d, unsigned len, nlen = OMAPI_DATA_STRING_EMPTY_SIZE + len; if (nlen < len) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; new = dmalloc (nlen, file, line); if (!new) return ISC_R_NOMEMORY; @@ -950,14 +950,14 @@ isc_result_t omapi_data_string_reference (omapi_data_string_t **r, const char *file, int line) { if (!h || !r) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (*r) { #if defined (POINTER_DEBUG) log_error ("%s(%d): reference store into non-null pointer!", file, line); abort (); #else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } *r = h; @@ -970,14 +970,14 @@ isc_result_t omapi_data_string_dereference (omapi_data_string_t **h, const char *file, int line) { if (!h) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (!*h) { #if defined (POINTER_DEBUG) log_error ("%s(%d): dereference of null pointer!", file, line); abort (); #else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } @@ -991,7 +991,7 @@ isc_result_t omapi_data_string_dereference (omapi_data_string_t **h, abort (); #else *h = 0; - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } @@ -1021,7 +1021,7 @@ isc_result_t omapi_value_reference (omapi_value_t **r, const char *file, int line) { if (!h || !r) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (*r) { #if defined (POINTER_DEBUG) @@ -1029,7 +1029,7 @@ isc_result_t omapi_value_reference (omapi_value_t **r, file, line); abort (); #else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } *r = h; @@ -1042,14 +1042,14 @@ isc_result_t omapi_value_dereference (omapi_value_t **h, const char *file, int line) { if (!h) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (!*h) { #if defined (POINTER_DEBUG) log_error ("%s(%d): dereference of null pointer!", file, line); abort (); #else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } @@ -1063,7 +1063,7 @@ isc_result_t omapi_value_dereference (omapi_value_t **h, abort (); #else *h = 0; - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } @@ -1103,7 +1103,7 @@ isc_result_t omapi_addr_list_reference (omapi_addr_list_t **r, const char *file, int line) { if (!h || !r) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (*r) { #if defined (POINTER_DEBUG) @@ -1111,7 +1111,7 @@ isc_result_t omapi_addr_list_reference (omapi_addr_list_t **r, file, line); abort (); #else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } *r = h; @@ -1124,14 +1124,14 @@ isc_result_t omapi_addr_list_dereference (omapi_addr_list_t **h, const char *file, int line) { if (!h) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (!*h) { #if defined (POINTER_DEBUG) log_error ("%s(%d): dereference of null pointer!", file, line); abort (); #else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } @@ -1145,7 +1145,7 @@ isc_result_t omapi_addr_list_dereference (omapi_addr_list_t **h, abort (); #else *h = 0; - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #endif } diff --git a/omapip/array.c b/omapip/array.c index f361b110..f42993ae 100644 --- a/omapip/array.c +++ b/omapip/array.c @@ -46,7 +46,7 @@ isc_result_t omapi_array_allocate (omapi_array_t **array, omapi_array_t *aptr; if (!array || *array) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; aptr = dmalloc (sizeof (omapi_array_t),file, line); if (!aptr) return ISC_R_NOMEMORY; @@ -63,7 +63,7 @@ isc_result_t omapi_array_free (omapi_array_t **array, int i; if (!array || !*array) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; aptr = *array; for (i = 0; i < aptr -> count; i++) if (aptr -> data [i] && aptr -> deref) @@ -98,11 +98,11 @@ isc_result_t omapi_array_set (omapi_array_t *array, void *ptr, int index, isc_result_t status; if (!array) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (!ptr) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (index < 0) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* If the proposed index is larger than the current available space in the array, make more space in the array. */ @@ -153,7 +153,7 @@ isc_result_t omapi_array_lookup (char **ptr, omapi_array_t *array, int index, const char *file, int line) { if (!array || !ptr || *ptr || index < 0 || index >= array -> count) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (array -> data [index]) return (*array -> ref) (ptr, array -> data [index], file, line); diff --git a/omapip/auth.c b/omapip/auth.c index 021b5a62..2f0b430c 100644 --- a/omapip/auth.c +++ b/omapip/auth.c @@ -57,19 +57,21 @@ isc_result_t omapi_auth_key_destroy (omapi_object_t *h, { omapi_auth_key_t *a; - if (h -> type != omapi_type_auth_key) - return ISC_R_INVALIDARG; + if (h->type != omapi_type_auth_key) + return DHCP_R_INVALIDARG; a = (omapi_auth_key_t *)h; - if (auth_key_hash) - omapi_auth_key_hash_delete (auth_key_hash, a -> name, 0, MDL); + if (auth_key_hash != NULL) + omapi_auth_key_hash_delete(auth_key_hash, a->name, 0, MDL); - if (a -> name) - dfree (a -> name, MDL); - if (a -> algorithm) - dfree (a -> algorithm, MDL); - if (a -> key) - omapi_data_string_dereference (&a -> key, MDL); + if (a->name != NULL) + dfree(a->name, MDL); + if (a->algorithm != NULL) + dfree(a->algorithm, MDL); + if (a->key != NULL) + omapi_data_string_dereference(&a->key, MDL); + if (a->tsec_key != NULL) + dns_tsec_destroy(&a->tsec_key); return ISC_R_SUCCESS; } @@ -77,9 +79,11 @@ isc_result_t omapi_auth_key_destroy (omapi_object_t *h, isc_result_t omapi_auth_key_enter (omapi_auth_key_t *a) { omapi_auth_key_t *tk; + isc_result_t status; + dst_key_t *dstkey; if (a -> type != omapi_type_auth_key) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; tk = (omapi_auth_key_t *)0; if (auth_key_hash) { @@ -99,9 +103,28 @@ isc_result_t omapi_auth_key_enter (omapi_auth_key_t *a) KEY_HASH_SIZE, MDL)) return ISC_R_NOMEMORY; } + + /* + * If possible create a tsec structure for this key, + * if we can't create the structure we put out a warning + * and continue. + */ + status = isclib_make_dst_key(a->name, a->algorithm, + a->key->value, a->key->len, + &dstkey); + if (status == ISC_R_SUCCESS) { + status = dns_tsec_create(dhcp_gbl_ctx.mctx, dns_tsectype_tsig, + dstkey, &a->tsec_key); + } + if (status != ISC_R_SUCCESS) { + if (dstkey != NULL) { + dst_key_free(&dstkey); + } + log_error("Unable to create tsec structure for %s", a->name); + } + omapi_auth_key_hash_add (auth_key_hash, a -> name, 0, a, MDL); return ISC_R_SUCCESS; - } isc_result_t omapi_auth_key_lookup_name (omapi_auth_key_t **a, @@ -126,7 +149,7 @@ isc_result_t omapi_auth_key_lookup (omapi_object_t **h, return ISC_R_NOTFOUND; if (!ref) - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; status = omapi_get_value_str (ref, id, "name", &name); if (status != ISC_R_SUCCESS) @@ -183,7 +206,7 @@ isc_result_t omapi_auth_key_stuff_values (omapi_object_t *c, isc_result_t status; if (h -> type != omapi_type_auth_key) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; a = (omapi_auth_key_t *)h; /* Write only the name and algorithm -- not the secret! */ diff --git a/omapip/buffer.c b/omapip/buffer.c index 1a47a181..1d6ee63a 100644 --- a/omapip/buffer.c +++ b/omapip/buffer.c @@ -154,7 +154,7 @@ static isc_result_t omapi_connection_reader_trace (omapi_object_t *h, unsigned bytes_to_read; if (!h || h -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; c = (omapi_connection_object_t *)h; /* See if there are enough bytes. */ @@ -216,7 +216,7 @@ static isc_result_t omapi_connection_reader_trace (omapi_object_t *h, else if (errno == EIO) return ISC_R_IOERROR; else if (errno == EINVAL) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; else if (errno == ECONNRESET) { omapi_disconnect (h, 1); return ISC_R_SHUTTINGDOWN; @@ -281,9 +281,9 @@ isc_result_t omapi_connection_copyin (omapi_object_t *h, /* Make sure len is valid. */ if (len < 0) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (!h || h -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; c = (omapi_connection_object_t *)h; /* If the connection is closed, return an error if the caller @@ -299,7 +299,7 @@ isc_result_t omapi_connection_copyin (omapi_object_t *h, } else { status = omapi_buffer_new (&c -> outbufs, MDL); if (status != ISC_R_SUCCESS) - return status; + goto leave; buffer = c -> outbufs; } @@ -309,7 +309,7 @@ isc_result_t omapi_connection_copyin (omapi_object_t *h, if (!BUFFER_BYTES_FREE (buffer)) { status = (omapi_buffer_new (&buffer -> next, MDL)); if (status != ISC_R_SUCCESS) - return status; + goto leave; buffer = buffer -> next; } @@ -329,7 +329,7 @@ isc_result_t omapi_connection_copyin (omapi_object_t *h, &bufp [bytes_copied], copy_len, (omapi_typed_data_t **)0); if (status != ISC_R_SUCCESS) - return status; + goto leave; } memcpy (&buffer -> buf [buffer -> tail], @@ -340,7 +340,25 @@ isc_result_t omapi_connection_copyin (omapi_object_t *h, if (buffer -> tail == sizeof buffer -> buf) buffer -> tail = 0; } - return ISC_R_SUCCESS; + + status = ISC_R_SUCCESS; + + leave: + /* + * If we have any bytes to send and we have a proper io object + * inform the socket code that we would like to know when we + * can send more bytes. + */ + if (c->out_bytes != 0) { + if ((c->outer != NULL) && + (c->outer->type == omapi_type_io_object)) { + omapi_io_object_t *io = (omapi_io_object_t *)c->outer; + isc_socket_fdwatchpoke(io->fd, + ISC_SOCKFDWATCH_WRITE); + } + } + + return (status); } /* Copy some bytes from the input buffer, and advance the input buffer @@ -360,7 +378,7 @@ isc_result_t omapi_connection_copyout (unsigned char *buf, isc_result_t status; if (!h || h -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; c = (omapi_connection_object_t *)h; if (size > c -> in_bytes) @@ -444,7 +462,7 @@ isc_result_t omapi_connection_writer (omapi_object_t *h) omapi_connection_object_t *c; if (!h || h -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; c = (omapi_connection_object_t *)h; /* Already flushed... */ @@ -478,7 +496,7 @@ isc_result_t omapi_connection_writer (omapi_object_t *h) are really errors. */ if (bytes_written < 0) { if (errno == EWOULDBLOCK || errno == EAGAIN) - return ISC_R_SUCCESS; + return ISC_R_INPROGRESS; else if (errno == EPIPE) return ISC_R_NOCONN; #ifdef EDQUOT @@ -492,14 +510,14 @@ isc_result_t omapi_connection_writer (omapi_object_t *h) else if (errno == EIO) return ISC_R_IOERROR; else if (errno == EINVAL) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; else if (errno == ECONNRESET) return ISC_R_SHUTTINGDOWN; else return ISC_R_UNEXPECTED; } if (bytes_written == 0) - return ISC_R_SUCCESS; + return ISC_R_INPROGRESS; #if defined (TRACING) if (trace_record ()) { @@ -533,7 +551,7 @@ isc_result_t omapi_connection_writer (omapi_object_t *h) O.S. output buffer and a further write would block, so stop trying to flush now. */ if (bytes_written != bytes_this_write) - return ISC_R_SUCCESS; + return ISC_R_INPROGRESS; } if (!BYTES_IN_BUFFER (buffer)) @@ -653,7 +671,7 @@ isc_result_t omapi_connection_write_typed_data (omapi_object_t *c, return omapi_connection_put_uint32 (c, handle); } - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } isc_result_t omapi_connection_put_name (omapi_object_t *c, const char *name) diff --git a/omapip/connection.c b/omapip/connection.c index e9289643..b32ee748 100644 --- a/omapip/connection.c +++ b/omapip/connection.c @@ -39,7 +39,6 @@ #include #include - #if defined (TRACING) static void trace_connect_input (trace_type_t *, unsigned, char *); static void trace_connect_stop (trace_type_t *); @@ -73,11 +72,11 @@ isc_result_t omapi_connect (omapi_object_t *c, name. It's okay for this call to block. */ he = gethostbyname (server_name); if (!he) - return ISC_R_HOSTUNKNOWN; + return DHCP_R_HOSTUNKNOWN; for (i = 0; he -> h_addr_list [i]; i++) ; if (i == 0) - return ISC_R_HOSTUNKNOWN; + return DHCP_R_HOSTUNKNOWN; hix = i; status = omapi_addr_list_new (&addrs, hix, MDL); @@ -158,7 +157,7 @@ isc_result_t omapi_connect_list (omapi_object_t *c, /* Only do TCPv4 so far. */ if (local_addr -> addrtype != AF_INET) { omapi_connection_dereference (&obj, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } local_sin.sin_port = htons (local_addr -> port); memcpy (&local_sin.sin_addr, @@ -444,7 +443,7 @@ isc_result_t omapi_disconnect (omapi_object_t *h, c = (omapi_connection_object_t *)h; if (c -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #if defined (TRACING) if (trace_record ()) { @@ -488,12 +487,27 @@ isc_result_t omapi_disconnect (omapi_object_t *h, #endif c -> state = omapi_connection_closed; +#if 0 + /* + * Disconnecting from the I/O object seems incorrect as it doesn't + * cause the I/O object to be cleaned and released. Previous to + * using the isc socket library this wouldn't have caused a problem + * with the socket library we would have a reference to a closed + * socket. Instead we now do an unregister to properly free the + * I/O object. + */ + /* Disconnect from I/O object, if any. */ if (h -> outer) { if (h -> outer -> inner) omapi_object_dereference (&h -> outer -> inner, MDL); omapi_object_dereference (&h -> outer, MDL); } +#else + if (h->outer) { + omapi_unregister_io_object(h); + } +#endif /* If whatever created us registered a signal handler, send it a disconnect signal. */ @@ -528,20 +542,18 @@ isc_result_t omapi_connection_require (omapi_object_t *h, unsigned bytes) omapi_connection_object_t *c; if (h -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; c = (omapi_connection_object_t *)h; c -> bytes_needed = bytes; if (c -> bytes_needed <= c -> in_bytes) { return ISC_R_SUCCESS; } - return ISC_R_NOTYET; + return DHCP_R_NOTYET; } /* Return the socket on which the dispatcher should wait for readiness - to read, for a connection object. If we already have more bytes than - we need to do the next thing, and we have at least a single full input - buffer, then don't indicate that we're ready to read. */ + to read, for a connection object. */ int omapi_connection_readfd (omapi_object_t *h) { omapi_connection_object_t *c; @@ -550,27 +562,22 @@ int omapi_connection_readfd (omapi_object_t *h) c = (omapi_connection_object_t *)h; if (c -> state != omapi_connection_connected) return -1; - if (c -> in_bytes >= OMAPI_BUF_SIZE - 1 && - c -> in_bytes > c -> bytes_needed) - return -1; return c -> socket; } -/* Return the socket on which the dispatcher should wait for readiness - to write, for a connection object. If there are no bytes buffered - for writing, then don't indicate that we're ready to write. */ +/* + * Return the socket on which the dispatcher should wait for readiness + * to write, for a connection object. When bytes are buffered we should + * also poke the dispatcher to tell it to start or re-start watching the + * socket. + */ int omapi_connection_writefd (omapi_object_t *h) { omapi_connection_object_t *c; if (h -> type != omapi_type_connection) return -1; c = (omapi_connection_object_t *)h; - if (c -> state == omapi_connection_connecting) - return c -> socket; - if (c -> out_bytes) - return c -> socket; - else - return -1; + return c->socket; } isc_result_t omapi_connection_connect (omapi_object_t *h) @@ -591,7 +598,7 @@ static isc_result_t omapi_connection_connect_internal (omapi_object_t *h) isc_result_t status; if (h -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; c = (omapi_connection_object_t *)h; if (c -> state == omapi_connection_connecting) { @@ -625,7 +632,7 @@ static isc_result_t omapi_connection_connect_internal (omapi_object_t *h) if (c -> connect_list -> addresses [c -> cptr].addrtype != AF_INET) { omapi_disconnect (h, 1); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } memcpy (&c -> remote_addr.sin_addr, @@ -662,7 +669,7 @@ static isc_result_t omapi_connection_connect_internal (omapi_object_t *h) return status; } c -> state = omapi_connection_connecting; - return ISC_R_INCOMPLETE; + return DHCP_R_INCOMPLETE; } c -> state = omapi_connection_connected; } @@ -704,7 +711,7 @@ isc_result_t omapi_connection_reaper (omapi_object_t *h) omapi_connection_object_t *c; if (h -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; c = (omapi_connection_object_t *)h; if (c -> state == omapi_connection_disconnecting && @@ -723,11 +730,10 @@ isc_result_t omapi_connection_reaper (omapi_object_t *h) return ISC_R_SUCCESS; } -static isc_result_t make_dst_key (DST_KEY **dst_key, omapi_object_t *a) { +static isc_result_t make_dst_key (dst_key_t **dst_key, omapi_object_t *a) { omapi_value_t *name = (omapi_value_t *)0; omapi_value_t *algorithm = (omapi_value_t *)0; omapi_value_t *key = (omapi_value_t *)0; - int algorithm_id = UNKNOWN_KEYALG; char *name_str = NULL; isc_result_t status = ISC_R_SUCCESS; @@ -744,14 +750,12 @@ static isc_result_t make_dst_key (DST_KEY **dst_key, omapi_object_t *a) { (a, (omapi_object_t *)0, "key", &key); if (status == ISC_R_SUCCESS) { - if ((algorithm -> value -> type == omapi_datatype_data || - algorithm -> value -> type == omapi_datatype_string) && - strncasecmp ((char *)algorithm -> value -> u.buffer.value, - NS_TSIG_ALG_HMAC_MD5 ".", - algorithm -> value -> u.buffer.len) == 0) { - algorithm_id = KEY_HMAC_MD5; - } else { - status = ISC_R_INVALIDARG; + if ((algorithm->value->type != omapi_datatype_data && + algorithm->value->type != omapi_datatype_string) || + strncasecmp((char *)algorithm->value->u.buffer.value, + NS_TSIG_ALG_HMAC_MD5 ".", + algorithm->value->u.buffer.len) != 0) { + status = DHCP_R_INVALIDARG; } } @@ -767,10 +771,13 @@ static isc_result_t make_dst_key (DST_KEY **dst_key, omapi_object_t *a) { name -> value -> u.buffer.len); name_str [name -> value -> u.buffer.len] = 0; - *dst_key = dst_buffer_to_key (name_str, algorithm_id, 0, 0, - key -> value -> u.buffer.value, - key -> value -> u.buffer.len); - if (!*dst_key) + status = isclib_make_dst_key(name_str, + DHCP_HMAC_MD5_NAME, + key->value->u.buffer.value, + key->value->u.buffer.len, + dst_key); + + if (*dst_key == NULL) status = ISC_R_NOMEMORY; } @@ -787,7 +794,7 @@ static isc_result_t make_dst_key (DST_KEY **dst_key, omapi_object_t *a) { } isc_result_t omapi_connection_sign_data (int mode, - DST_KEY *key, + dst_key_t *key, void **context, const unsigned char *data, const unsigned len, @@ -795,37 +802,62 @@ isc_result_t omapi_connection_sign_data (int mode, { omapi_typed_data_t *td = (omapi_typed_data_t *)0; isc_result_t status; - int r; + dst_context_t **dctx = (dst_context_t **)context; + /* Create the context for the dst module */ + if (mode & SIG_MODE_INIT) { + status = dst_context_create(key, dhcp_gbl_ctx.mctx, dctx); + if (status != ISC_R_SUCCESS) { + return status; + } + } + + /* If we have any data add it to the context */ + if (len != 0) { + isc_region_t region; + region.base = (unsigned char *)data; + region.length = len; + dst_context_adddata(*dctx, ®ion); + } + + /* Finish the signature and clean up the context */ if (mode & SIG_MODE_FINAL) { + unsigned int sigsize; + isc_buffer_t sigbuf; + + status = dst_key_sigsize(key, &sigsize); + if (status != ISC_R_SUCCESS) { + goto cleanup; + } + status = omapi_typed_data_new (MDL, &td, omapi_datatype_data, - dst_sig_size (key)); - if (status != ISC_R_SUCCESS) - return status; - } + sigsize); + if (status != ISC_R_SUCCESS) { + goto cleanup; + } - r = dst_sign_data (mode, key, context, data, len, - td ? td -> u.buffer.value : (u_char *)0, - td ? td -> u.buffer.len : 0); + isc_buffer_init(&sigbuf, td->u.buffer.value, td->u.buffer.len); + status = dst_context_sign(*dctx, &sigbuf); + if (status != ISC_R_SUCCESS) { + goto cleanup; + } - /* dst_sign_data() really should do this for us, shouldn't it? */ - if (mode & SIG_MODE_FINAL) - *context = (void *)0; + if (result) { + omapi_typed_data_reference (result, td, MDL); + } - if (r < 0) { - if (td) + cleanup: + /* We are done with the context and the td. On success + * the td is now referenced from result, on failure we + * don't need it any more */ + if (td) { omapi_typed_data_dereference (&td, MDL); - return ISC_R_INVALIDKEY; + } + dst_context_destroy(dctx); + return status; } - if (result && td) { - omapi_typed_data_reference (result, td, MDL); - } - - if (td) - omapi_typed_data_dereference (&td, MDL); - return ISC_R_SUCCESS; } @@ -834,15 +866,14 @@ isc_result_t omapi_connection_output_auth_length (omapi_object_t *h, { omapi_connection_object_t *c; - if (h -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + if (h->type != omapi_type_connection) + return DHCP_R_INVALIDARG; c = (omapi_connection_object_t *)h; - if (!c -> out_key) + if (c->out_key == NULL) return ISC_R_NOTFOUND; - *l = dst_sig_size (c -> out_key); - return ISC_R_SUCCESS; + return(dst_key_sigsize(c->out_key, l)); } isc_result_t omapi_connection_set_value (omapi_object_t *h, @@ -854,12 +885,12 @@ isc_result_t omapi_connection_set_value (omapi_object_t *h, isc_result_t status; if (h -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; c = (omapi_connection_object_t *)h; if (omapi_ds_strcmp (name, "input-authenticator") == 0) { if (value && value -> type != omapi_datatype_object) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (c -> in_context) { omapi_connection_sign_data (SIG_MODE_FINAL, @@ -869,9 +900,8 @@ isc_result_t omapi_connection_set_value (omapi_object_t *h, (omapi_typed_data_t **) 0); } - if (c -> in_key) { - dst_free_key (c -> in_key); - c -> in_key = (DST_KEY *)0; + if (c->in_key != NULL) { + dst_key_free(&c->in_key); } if (value) { @@ -885,7 +915,7 @@ isc_result_t omapi_connection_set_value (omapi_object_t *h, } else if (omapi_ds_strcmp (name, "output-authenticator") == 0) { if (value && value -> type != omapi_datatype_object) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (c -> out_context) { omapi_connection_sign_data (SIG_MODE_FINAL, @@ -895,9 +925,8 @@ isc_result_t omapi_connection_set_value (omapi_object_t *h, (omapi_typed_data_t **) 0); } - if (c -> out_key) { - dst_free_key (c -> out_key); - c -> out_key = (DST_KEY *)0; + if (c->out_key != NULL) { + dst_key_free(&c->out_key); } if (value) { @@ -924,9 +953,10 @@ isc_result_t omapi_connection_get_value (omapi_object_t *h, omapi_connection_object_t *c; omapi_typed_data_t *td = (omapi_typed_data_t *)0; isc_result_t status; + unsigned int sigsize; if (h -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; c = (omapi_connection_object_t *)h; if (omapi_ds_strcmp (name, "input-signature") == 0) { @@ -945,11 +975,15 @@ isc_result_t omapi_connection_get_value (omapi_object_t *h, return status; } else if (omapi_ds_strcmp (name, "input-signature-size") == 0) { - if (!c -> in_key) + if (c->in_key == NULL) return ISC_R_NOTFOUND; - return omapi_make_int_value (value, name, - dst_sig_size (c -> in_key), MDL); + status = dst_key_sigsize(c->in_key, &sigsize); + if (status != ISC_R_SUCCESS) { + return(status); + } + + return omapi_make_int_value(value, name, sigsize, MDL); } else if (omapi_ds_strcmp (name, "output-signature") == 0) { if (!c -> out_key || !c -> out_context) @@ -967,11 +1001,16 @@ isc_result_t omapi_connection_get_value (omapi_object_t *h, return status; } else if (omapi_ds_strcmp (name, "output-signature-size") == 0) { - if (!c -> out_key) + if (c->out_key == NULL) return ISC_R_NOTFOUND; - return omapi_make_int_value (value, name, - dst_sig_size (c -> out_key), MDL); + + status = dst_key_sigsize(c->out_key, &sigsize); + if (status != ISC_R_SUCCESS) { + return(status); + } + + return omapi_make_int_value(value, name, sigsize, MDL); } if (h -> inner && h -> inner -> type -> get_value) @@ -1005,7 +1044,7 @@ isc_result_t omapi_connection_signal_handler (omapi_object_t *h, const char *name, va_list ap) { if (h -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; #ifdef DEBUG_PROTOCOL log_debug ("omapi_connection_signal_handler(%s)", name); @@ -1025,7 +1064,7 @@ isc_result_t omapi_connection_stuff_values (omapi_object_t *c, omapi_object_t *m) { if (m -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (m -> inner && m -> inner -> type -> stuff_values) return (*(m -> inner -> type -> stuff_values)) (c, id, diff --git a/omapip/dispatch.c b/omapip/dispatch.c index 9e3fb8ae..887a337b 100644 --- a/omapip/dispatch.c +++ b/omapip/dispatch.c @@ -104,6 +104,60 @@ trigger_event(struct eventqueue **queue) } } +/* + * Callback routine to connect the omapi I/O object and socket with + * the isc socket code. The isc socket code will call this routine + * which will then call the correct local routine to process the bytes. + * + * Currently we are always willing to read more data, this should be modified + * so that on connections we don't read more if we already have enough. + * + * If we have more bytes to write we ask the library to call us when + * we can write more. If we indicate we don't have more to write we need + * to poke the library via isc_socket_fdwatchpoke. + */ +int +omapi_iscsock_cb(isc_task_t *task, + isc_socket_t *socket, + void *cbarg, + int flags) +{ + omapi_io_object_t *obj; + isc_result_t status; + + /* Get the current time... */ + gettimeofday (&cur_tv, (struct timezone *)0); + + /* Not much to be done if we have the wrong type of object. */ + if (((omapi_object_t *)cbarg) -> type != omapi_type_io_object) { + log_fatal ("Incorrect object type, must be of type io_object"); + } + obj = (omapi_io_object_t *)cbarg; + + if ((flags == ISC_SOCKFDWATCH_READ) && + (obj->reader != NULL) && + (obj->inner != NULL)) { + obj->reader(obj->inner); + /* We always ask for more when reading */ + return (1); + } else if ((flags == ISC_SOCKFDWATCH_WRITE) && + (obj->writer != NULL) && + (obj->inner != NULL)) { + status = obj->writer(obj->inner); + /* If the writer has more to write they should return + * ISC_R_INPROGRESS */ + if (status == ISC_R_INPROGRESS) { + return (1); + } + } + + /* + * We get here if we either had an error (inconsistent + * structures etc) or no more to write, tell the socket + * lib we don't have more to do right now. + */ + return (0); +} /* Register an I/O handle so that we can do asynchronous I/O on it. */ @@ -119,6 +173,7 @@ isc_result_t omapi_register_io_object (omapi_object_t *h, { isc_result_t status; omapi_io_object_t *obj, *p; + int fd_flags = 0, fd = 0; /* omapi_io_states is a static object. If its reference count is zero, this is the first I/O handle to be registered, so @@ -148,6 +203,43 @@ isc_result_t omapi_register_io_object (omapi_object_t *h, return status; } + /* + * Attach the I/O object to the isc socket library via the + * fdwatch function. This allows the socket library to watch + * over a socket that we built. If there are both a read and + * a write socket we asssume they are the same socket. + */ + + if (readfd) { + fd_flags |= ISC_SOCKFDWATCH_READ; + fd = readfd(h); + } + + if (writefd) { + fd_flags |= ISC_SOCKFDWATCH_WRITE; + fd = writefd(h); + } + + if (fd_flags != 0) { + status = isc_socket_fdwatchcreate(dhcp_gbl_ctx.socketmgr, + fd, fd_flags, + omapi_iscsock_cb, + obj, + dhcp_gbl_ctx.task, + &obj->fd); + if (status != ISC_R_SUCCESS) { + log_error("Unable to register fd with library %s", + isc_result_totext(status)); + + /*sar*/ + /* is this the cleanup we need? */ + omapi_object_dereference(&h->outer, MDL); + omapi_io_dereference (&obj, MDL); + return (status); + } + } + + /* Find the last I/O state, if there are any. */ for (p = omapi_io_states.next; p && p -> next; p = p -> next) @@ -216,7 +308,7 @@ isc_result_t omapi_unregister_io_object (omapi_object_t *h) omapi_io_object_t *p, *obj, *last, *ph; if (!h -> outer || h -> outer -> type != omapi_type_io_object) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; obj = (omapi_io_object_t *)h -> outer; ph = (omapi_io_object_t *)0; omapi_io_reference (&ph, obj, MDL); @@ -242,6 +334,12 @@ isc_result_t omapi_unregister_io_object (omapi_object_t *h) } omapi_object_dereference (&obj -> inner, MDL); omapi_object_dereference (&h -> outer, MDL); + + /* remove isc socket associations */ + if (obj->fd != NULL) { + isc_socket_detach(&obj->fd); + } + omapi_io_dereference (&ph, MDL); return ISC_R_SUCCESS; } @@ -577,7 +675,6 @@ isc_result_t omapi_one_dispatch (omapi_object_t *wo, omapi_io_dereference(&prev, MDL); } omapi_io_reference(&prev, io, MDL); - } /* @@ -608,7 +705,7 @@ isc_result_t omapi_io_set_value (omapi_object_t *h, omapi_typed_data_t *value) { if (h -> type != omapi_type_io_object) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (h -> inner && h -> inner -> type -> set_value) return (*(h -> inner -> type -> set_value)) @@ -622,7 +719,7 @@ isc_result_t omapi_io_get_value (omapi_object_t *h, omapi_value_t **value) { if (h -> type != omapi_type_io_object) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (h -> inner && h -> inner -> type -> get_value) return (*(h -> inner -> type -> get_value)) @@ -643,7 +740,7 @@ isc_result_t omapi_io_destroy (omapi_object_t *h, const char *file, int line) omapi_io_object_t *obj = NULL, *p, *last = NULL, **holder; if (h -> type != omapi_type_io_object) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* remove from the list of I/O states */ for (p = omapi_io_states.next; p; p = p -> next) { @@ -674,7 +771,7 @@ isc_result_t omapi_io_signal_handler (omapi_object_t *h, const char *name, va_list ap) { if (h -> type != omapi_type_io_object) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (h -> inner && h -> inner -> type -> signal_handler) return (*(h -> inner -> type -> signal_handler)) (h -> inner, @@ -687,7 +784,7 @@ isc_result_t omapi_io_stuff_values (omapi_object_t *c, omapi_object_t *i) { if (i -> type != omapi_type_io_object) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (i -> inner && i -> inner -> type -> stuff_values) return (*(i -> inner -> type -> stuff_values)) (c, id, @@ -701,7 +798,7 @@ isc_result_t omapi_waiter_signal_handler (omapi_object_t *h, omapi_waiter_object_t *waiter; if (h -> type != omapi_type_waiter) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (!strcmp (name, "ready")) { waiter = (omapi_waiter_object_t *)h; @@ -710,17 +807,17 @@ isc_result_t omapi_waiter_signal_handler (omapi_object_t *h, return ISC_R_SUCCESS; } - if (!strcmp (name, "status")) { + if (!strcmp(name, "status")) { waiter = (omapi_waiter_object_t *)h; - waiter -> ready = 1; - waiter -> waitstatus = va_arg (ap, isc_result_t); + waiter->ready = 1; + waiter->waitstatus = va_arg(ap, isc_result_t); return ISC_R_SUCCESS; } if (!strcmp (name, "disconnect")) { waiter = (omapi_waiter_object_t *)h; waiter -> ready = 1; - waiter -> waitstatus = ISC_R_CONNRESET; + waiter -> waitstatus = DHCP_R_CONNRESET; return ISC_R_SUCCESS; } diff --git a/omapip/generic.c b/omapip/generic.c index da3c9d7c..bd18f337 100644 --- a/omapip/generic.c +++ b/omapip/generic.c @@ -61,7 +61,7 @@ isc_result_t omapi_generic_set_value (omapi_object_t *h, isc_result_t status; if (h -> type != omapi_type_generic) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; g = (omapi_generic_object_t *)h; /* See if there's already a value with this name attached to @@ -177,7 +177,7 @@ isc_result_t omapi_generic_get_value (omapi_object_t *h, omapi_generic_object_t *g; if (h -> type != omapi_type_generic) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; g = (omapi_generic_object_t *)h; /* Look up the specified name in our list of objects. */ @@ -232,7 +232,7 @@ isc_result_t omapi_generic_signal_handler (omapi_object_t *h, const char *name, va_list ap) { if (h -> type != omapi_type_generic) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (h -> inner && h -> inner -> type -> signal_handler) return (*(h -> inner -> type -> signal_handler)) (h -> inner, @@ -252,7 +252,7 @@ isc_result_t omapi_generic_stuff_values (omapi_object_t *c, isc_result_t status; if (g -> type != omapi_type_generic) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; src = (omapi_generic_object_t *)g; for (i = 0; i < src -> nvalues; i++) { @@ -292,7 +292,7 @@ isc_result_t omapi_generic_clear_flags (omapi_object_t *o) omapi_generic_object_t *g; if (o -> type != omapi_type_generic) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; g = (omapi_generic_object_t *)o; for (i = 0; i < g -> nvalues; i++) { diff --git a/omapip/handle.c b/omapip/handle.c index a65c3e4b..b7e72ca7 100644 --- a/omapip/handle.c +++ b/omapip/handle.c @@ -290,6 +290,6 @@ isc_result_t omapi_handle_td_lookup (omapi_object_t **obj, memcpy (&h, handle -> u.buffer.value, sizeof h); h = ntohl (h); } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return omapi_handle_lookup (obj, h); } diff --git a/omapip/isclib.c b/omapip/isclib.c new file mode 100644 index 00000000..f4cb46a6 --- /dev/null +++ b/omapip/isclib.c @@ -0,0 +1,230 @@ +/* + * Copyright(c) 2009 by Internet Systems Consortium, Inc.("ISC") + * + * 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. + * + * Internet Systems Consortium, Inc. + * 950 Charter Street + * Redwood City, CA 94063 + * + * http://www.isc.org/ + * + */ + +/*Trying to figure out what we need to define to get things to work. + It looks like we want/need the export library but need the fdwatchcommand + which may be a problem */ + +#include "dhcpd.h" + +dhcp_context_t dhcp_gbl_ctx; + +void +isclib_cleanup(void) +{ +#if defined (NSUPDATE) + if (dhcp_gbl_ctx.dnsclient != NULL) + dns_client_destroy((dns_client_t **)&dhcp_gbl_ctx.dnsclient); +#endif + + if (dhcp_gbl_ctx.task != NULL) { +// isc_task_destroy(&dhcp_gbl_ctx.task); + isc_task_shutdown(dhcp_gbl_ctx.task); + isc_task_detach(&dhcp_gbl_ctx.task); + } + + if (dhcp_gbl_ctx.timermgr != NULL) + isc_timermgr_destroy(&dhcp_gbl_ctx.timermgr); + + if (dhcp_gbl_ctx.socketmgr != NULL) + isc_socketmgr_destroy(&dhcp_gbl_ctx.socketmgr); + + if (dhcp_gbl_ctx.taskmgr != NULL) + isc_taskmgr_destroy(&dhcp_gbl_ctx.taskmgr); + + if (dhcp_gbl_ctx.actx_started != ISC_FALSE) { + isc_app_ctxfinish(dhcp_gbl_ctx.actx); + dhcp_gbl_ctx.actx_started = ISC_FALSE; + } + + if (dhcp_gbl_ctx.actx != NULL) + isc_appctx_destroy(&dhcp_gbl_ctx.actx); + + if (dhcp_gbl_ctx.mctx != NULL) + isc_mem_detach(&dhcp_gbl_ctx.mctx); + + return; +} + +isc_result_t +dhcp_context_create(void) { + isc_result_t result; + + /* + * Set up the error messages, this isn't the right place + * for this call but it is convienent for now. + */ + result = dhcp_result_register(); + if (result != ISC_R_SUCCESS) { + log_fatal("register_table() %s: %u", "failed", result); + } + + memset(&dhcp_gbl_ctx, 0, sizeof (dhcp_gbl_ctx)); + + isc_lib_register(); + + /* get the current time for use as the random seed */ + gettimeofday(&cur_tv, (struct timezone *)0); + isc_random_seed(cur_tv.tv_sec); + +#if defined (NSUPDATE) + result = dns_lib_init(); + if (result != ISC_R_SUCCESS) + goto cleanup; +#endif + + result = isc_mem_create(0, 0, &dhcp_gbl_ctx.mctx); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = isc_appctx_create(dhcp_gbl_ctx.mctx, &dhcp_gbl_ctx.actx); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = isc_app_ctxstart(dhcp_gbl_ctx.actx); + if (result != ISC_R_SUCCESS) + return (result); + dhcp_gbl_ctx.actx_started = ISC_TRUE; + + result = isc_taskmgr_createinctx(dhcp_gbl_ctx.mctx, + dhcp_gbl_ctx.actx, + 1, 0, + &dhcp_gbl_ctx.taskmgr); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = isc_socketmgr_createinctx(dhcp_gbl_ctx.mctx, + dhcp_gbl_ctx.actx, + &dhcp_gbl_ctx.socketmgr); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = isc_timermgr_createinctx(dhcp_gbl_ctx.mctx, + dhcp_gbl_ctx.actx, + &dhcp_gbl_ctx.timermgr); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = isc_task_create(dhcp_gbl_ctx.taskmgr, 0, &dhcp_gbl_ctx.task); + if (result != ISC_R_SUCCESS) + goto cleanup; + +#if defined (NSUPDATE) + result = dns_client_createx(dhcp_gbl_ctx.mctx, + dhcp_gbl_ctx.actx, + dhcp_gbl_ctx.taskmgr, + dhcp_gbl_ctx.socketmgr, + dhcp_gbl_ctx.timermgr, + 0, + &dhcp_gbl_ctx.dnsclient); + if (result != ISC_R_SUCCESS) + goto cleanup; +#else + /* The dst library is inited as part of dns_lib_init, we don't + * need it if NSUPDATE is enabled */ + result = dst_lib_init(dhcp_gbl_ctx.mctx, NULL, 0); + if (result != ISC_R_SUCCESS) + goto cleanup; + +#endif + return(ISC_R_SUCCESS); + + cleanup: + isclib_cleanup(); + + return(result); +} + +/* Convert a string name into the proper structure for the isc routines */ +isc_result_t +dhcp_isc_name(unsigned char *namestr, + dns_fixedname_t *namefix, + dns_name_t **name) +{ + size_t namelen; + isc_buffer_t b; + isc_result_t result; + + namelen = strlen((char *)namestr); + isc_buffer_init(&b, namestr, namelen); + isc_buffer_add(&b, namelen); + dns_fixedname_init(namefix); + *name = dns_fixedname_name(namefix); + result = dns_name_fromtext(*name, &b, NULL, 0, NULL); + isc_buffer_invalidate(&b); + return(result); +} + +isc_result_t +isclib_make_dst_key(char *inname, + char *algorithm, + unsigned char *secret, + int length, + dst_key_t **dstkey) +{ + isc_result_t result; + dns_name_t *name; + dns_fixedname_t name0; + isc_buffer_t b; + int namelen; + + isc_buffer_init(&b, secret, length); + isc_buffer_add(&b, length); + + /* We only support HMAC_MD5 currently */ + if (strcasecmp(algorithm, DHCP_HMAC_MD5_NAME) != 0) { + return(DHCP_R_INVALIDARG); + } + + /* + * Previously we allowed key names without a trailing '.' + * however the current dst code requires the names to end + * in a period. If the name doesn't have a trailing period + * add one before sending it to the dst code. + */ + namelen = strlen(inname); + if (inname[namelen-1] != '.') { + char *newname = NULL; + newname = (char *)dmalloc(namelen + 2, MDL); + if (newname == NULL) { + log_error("unable to allocate memory for key name"); + return(ISC_R_NOMEMORY); + } + strcpy(newname, inname); + newname[namelen] = '.'; + newname[namelen+1] = 0; + result = dhcp_isc_name((unsigned char *)newname, &name0, &name); + dfree(newname, MDL); + } else { + result = dhcp_isc_name((unsigned char *)inname, &name0, &name); + } + + if (result != ISC_R_SUCCESS) { + return(result); + } + + return(dst_key_frombuffer(name, DST_ALG_HMACMD5, DNS_KEYOWNER_ENTITY, + DNS_KEYPROTO_DNSSEC, dns_rdataclass_in, + &b, dhcp_gbl_ctx.mctx, dstkey)); +} + diff --git a/omapip/listener.c b/omapip/listener.c index 2d5c4fa2..3cdbec79 100644 --- a/omapip/listener.c +++ b/omapip/listener.c @@ -77,7 +77,7 @@ isc_result_t omapi_listen_addr (omapi_object_t *h, /* Currently only support IPv4 addresses. */ if (addr->addrtype != AF_INET) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* Get the handle. */ obj = (omapi_listener_object_t *)0; @@ -219,7 +219,7 @@ isc_result_t omapi_accept (omapi_object_t *h) int socket; if (h -> type != omapi_type_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; listener = (omapi_listener_object_t *)h; /* Accept the connection. */ @@ -392,7 +392,7 @@ isc_result_t omapi_listener_configure_security (omapi_object_t *h, omapi_listener_object_t *l; if (h -> type != omapi_type_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; l = (omapi_listener_object_t *)h; l -> verify_addr = verify_addr; @@ -406,7 +406,7 @@ isc_result_t omapi_listener_set_value (omapi_object_t *h, omapi_typed_data_t *value) { if (h -> type != omapi_type_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (h -> inner && h -> inner -> type -> set_value) return (*(h -> inner -> type -> set_value)) @@ -420,7 +420,7 @@ isc_result_t omapi_listener_get_value (omapi_object_t *h, omapi_value_t **value) { if (h -> type != omapi_type_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (h -> inner && h -> inner -> type -> get_value) return (*(h -> inner -> type -> get_value)) @@ -434,7 +434,7 @@ isc_result_t omapi_listener_destroy (omapi_object_t *h, omapi_listener_object_t *l; if (h -> type != omapi_type_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; l = (omapi_listener_object_t *)h; #ifdef DEBUG_PROTOCOL @@ -452,7 +452,7 @@ isc_result_t omapi_listener_signal_handler (omapi_object_t *h, const char *name, va_list ap) { if (h -> type != omapi_type_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (h -> inner && h -> inner -> type -> signal_handler) return (*(h -> inner -> type -> signal_handler)) (h -> inner, @@ -468,7 +468,7 @@ isc_result_t omapi_listener_stuff_values (omapi_object_t *c, omapi_object_t *l) { if (l -> type != omapi_type_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (l -> inner && l -> inner -> type -> stuff_values) return (*(l -> inner -> type -> stuff_values)) (c, id, diff --git a/omapip/message.c b/omapip/message.c index d1149583..6d8b88f3 100644 --- a/omapip/message.c +++ b/omapip/message.c @@ -91,7 +91,7 @@ isc_result_t omapi_message_set_value (omapi_object_t *h, isc_result_t status; if (h -> type != omapi_type_message) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; m = (omapi_message_object_t *)h; /* Can't set authlen. */ @@ -106,7 +106,7 @@ isc_result_t omapi_message_set_value (omapi_object_t *h, } else if (!omapi_ds_strcmp (name, "object")) { if (value -> type != omapi_datatype_object) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (m -> object) omapi_object_dereference (&m -> object, MDL); omapi_object_reference (&m -> object, value -> u.object, MDL); @@ -114,7 +114,7 @@ isc_result_t omapi_message_set_value (omapi_object_t *h, } else if (!omapi_ds_strcmp (name, "notify-object")) { if (value -> type != omapi_datatype_object) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (m -> notify_object) omapi_object_dereference (&m -> notify_object, MDL); omapi_object_reference (&m -> notify_object, @@ -124,35 +124,35 @@ isc_result_t omapi_message_set_value (omapi_object_t *h, /* Can set authid, but it has to be an integer. */ } else if (!omapi_ds_strcmp (name, "authid")) { if (value -> type != omapi_datatype_int) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; m -> authid = value -> u.integer; return ISC_R_SUCCESS; /* Can set op, but it has to be an integer. */ } else if (!omapi_ds_strcmp (name, "op")) { if (value -> type != omapi_datatype_int) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; m -> op = value -> u.integer; return ISC_R_SUCCESS; /* Handle also has to be an integer. */ } else if (!omapi_ds_strcmp (name, "handle")) { if (value -> type != omapi_datatype_int) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; m -> h = value -> u.integer; return ISC_R_SUCCESS; /* Transaction ID has to be an integer. */ } else if (!omapi_ds_strcmp (name, "id")) { if (value -> type != omapi_datatype_int) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; m -> id = value -> u.integer; return ISC_R_SUCCESS; /* Remote transaction ID has to be an integer. */ } else if (!omapi_ds_strcmp (name, "rid")) { if (value -> type != omapi_datatype_int) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; m -> rid = value -> u.integer; return ISC_R_SUCCESS; } @@ -175,7 +175,7 @@ isc_result_t omapi_message_get_value (omapi_object_t *h, { omapi_message_object_t *m; if (h -> type != omapi_type_message) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; m = (omapi_message_object_t *)h; /* Look for values that are in the message data structure. */ @@ -213,7 +213,7 @@ isc_result_t omapi_message_destroy (omapi_object_t *h, { omapi_message_object_t *m; if (h -> type != omapi_type_message) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; m = (omapi_message_object_t *)h; if (m -> authenticator) { omapi_typed_data_dereference (&m -> authenticator, file, line); @@ -236,7 +236,7 @@ isc_result_t omapi_message_signal_handler (omapi_object_t *h, { omapi_message_object_t *m; if (h -> type != omapi_type_message) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; m = (omapi_message_object_t *)h; if (!strcmp (name, "status")) { @@ -262,7 +262,7 @@ isc_result_t omapi_message_stuff_values (omapi_object_t *c, omapi_object_t *m) { if (m -> type != omapi_type_message) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (m -> inner && m -> inner -> type -> stuff_values) return (*(m -> inner -> type -> stuff_values)) (c, id, @@ -275,12 +275,12 @@ isc_result_t omapi_message_register (omapi_object_t *mo) omapi_message_object_t *m; if (mo -> type != omapi_type_message) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; m = (omapi_message_object_t *)mo; /* Already registered? */ if (m -> prev || m -> next || omapi_registered_messages == m) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (omapi_registered_messages) { omapi_object_reference @@ -304,12 +304,12 @@ isc_result_t omapi_message_unregister (omapi_object_t *mo) omapi_message_object_t *n; if (mo -> type != omapi_type_message) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; m = (omapi_message_object_t *)mo; /* Not registered? */ if (!m -> prev && omapi_registered_messages != m) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; n = (omapi_message_object_t *)0; if (m -> next) { @@ -398,7 +398,7 @@ omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po) omapi_object_type_t *type; if (mo -> type != omapi_type_message) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; message = (omapi_message_object_t *)mo; #ifdef DEBUG_PROTOCOL @@ -426,12 +426,12 @@ omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po) /* All messages must have an authenticator, with the exception of messages that are opening a new authenticator. */ - if (omapi_protocol_authenticated (po) && - !message -> id_object && - message -> op != OMAPI_OP_OPEN) { + if (omapi_protocol_authenticated(po) && + !message->id_object && + message->op != OMAPI_OP_OPEN) { return omapi_protocol_send_status - (po, message -> id_object, ISC_R_NOKEYS, - message -> id, "No authenticator on message"); + (po, message->id_object, DHCP_R_NOKEYS, + message->id, "No authenticator on message"); } } @@ -439,8 +439,8 @@ omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po) case OMAPI_OP_OPEN: if (m) { return omapi_protocol_send_status - (po, message -> id_object, ISC_R_INVALIDARG, - message -> id, "OPEN can't be a response"); + (po, message->id_object, DHCP_R_INVALIDARG, + message->id, "OPEN can't be a response"); } /* Get the type of the requested object, if one was @@ -462,12 +462,12 @@ omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po) /* If this object had no authenticator, the requested object must be an authenticator object. */ - if (omapi_protocol_authenticated (po) && - !message -> id_object && + if (omapi_protocol_authenticated(po) && + !message->id_object && type != omapi_type_auth_key) { return omapi_protocol_send_status - (po, message -> id_object, ISC_R_NOKEYS, - message -> id, "No authenticator on message"); + (po, message->id_object, DHCP_R_NOKEYS, + message->id, "No authenticator on message"); } /* Get the create flag. */ @@ -520,9 +520,9 @@ omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po) if (!type) { if (create) { return omapi_protocol_send_status - (po, message -> id_object, - ISC_R_INVALIDARG, - message -> id, + (po, message->id_object, + DHCP_R_INVALIDARG, + message->id, "type required on create"); } goto refresh; @@ -542,7 +542,7 @@ omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po) if (status != ISC_R_SUCCESS && status != ISC_R_NOTFOUND && - status != ISC_R_NOKEYS) { + status != DHCP_R_NOKEYS) { return omapi_protocol_send_status (po, message -> id_object, status, message -> id, diff --git a/omapip/mrtrace.c b/omapip/mrtrace.c index 23697440..57cf9157 100644 --- a/omapip/mrtrace.c +++ b/omapip/mrtrace.c @@ -33,7 +33,7 @@ #include "dhcpd.h" #include -#include "minires/minires.h" +#include "minires.h" #include "arpa/nameser.h" #include @@ -83,6 +83,7 @@ void trace_mr_init () trace_mr_randomid_stop, MDL); } +#if 0 void trace_mr_statp_setup (res_state statp) { unsigned buflen = 0; @@ -142,6 +143,7 @@ void trace_mr_statp_setup (res_state statp) } } #endif +#endif ssize_t trace_mr_send (int fd, void *msg, size_t len, int flags) { diff --git a/omapip/protocol.c b/omapip/protocol.c index c3a66367..e34508d0 100644 --- a/omapip/protocol.c +++ b/omapip/protocol.c @@ -59,7 +59,7 @@ isc_result_t omapi_protocol_connect (omapi_object_t *h, return status; rstatus = omapi_connect ((omapi_object_t *)obj, server_name, port); - if (rstatus != ISC_R_SUCCESS && rstatus != ISC_R_INCOMPLETE) { + if (rstatus != ISC_R_SUCCESS && rstatus != DHCP_R_INCOMPLETE) { omapi_protocol_dereference (&obj, MDL); return rstatus; } @@ -95,7 +95,7 @@ isc_result_t omapi_protocol_connect (omapi_object_t *h, } obj -> insecure = 0; - rstatus = ISC_R_INCOMPLETE; + rstatus = DHCP_R_INCOMPLETE; } else { obj -> insecure = 1; #if 0 @@ -120,7 +120,7 @@ isc_result_t omapi_protocol_send_intro (omapi_object_t *h, #endif if (h -> type != omapi_type_protocol) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; p = (omapi_protocol_object_t *)h; if (!h -> outer || h -> outer -> type != omapi_type_connection) @@ -139,7 +139,7 @@ isc_result_t omapi_protocol_send_intro (omapi_object_t *h, protocol input state machine. */ p -> state = omapi_protocol_intro_wait; status = omapi_connection_require (h -> outer, 8); - if (status != ISC_R_SUCCESS && status != ISC_R_NOTYET) + if (status != ISC_R_SUCCESS && status != DHCP_R_NOTYET) return status; /* Make up an initial transaction ID for this connection. */ @@ -167,9 +167,9 @@ isc_result_t omapi_protocol_send_message (omapi_object_t *po, if (po -> type != omapi_type_protocol || !po -> outer || po -> outer -> type != omapi_type_connection || mo -> type != omapi_type_message) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (omo && omo -> type != omapi_type_message) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; p = (omapi_protocol_object_t *)po; c = (omapi_object_t *)(po -> outer); m = (omapi_message_object_t *)mo; @@ -192,7 +192,7 @@ isc_result_t omapi_protocol_send_message (omapi_object_t *po, } if (!ra) - return ISC_R_KEY_UNKNOWN; + return DHCP_R_KEY_UNKNOWN; } else if (p -> remote_auth_list) { ra = p -> default_auth; } else { @@ -433,7 +433,7 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h, } if (!p -> outer || p -> outer -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; c = p -> outer; /* We get here because we requested that we be woken up after @@ -449,12 +449,12 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h, /* We currently only support the current protocol version. */ if (p -> protocol_version != OMAPI_PROTOCOL_VERSION) { omapi_disconnect (c, 1); - return ISC_R_VERSIONMISMATCH; + return DHCP_R_VERSIONMISMATCH; } if (p -> header_size < sizeof (omapi_protocol_header_t)) { omapi_disconnect (c, 1); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } if (p -> default_auth) { @@ -722,7 +722,7 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h, p -> message -> authenticator -> u.buffer.value, p -> message -> authlen) != 0))) { /* Invalid signature. */ - p -> verify_result = ISC_R_INVALIDKEY; + p->verify_result = DHCP_R_INVALIDKEY; } omapi_value_dereference (&signature, MDL); @@ -778,10 +778,10 @@ isc_result_t omapi_protocol_add_auth (omapi_object_t *po, if (ao -> type != omapi_type_auth_key && (!ao -> inner || ao -> inner -> type != omapi_type_auth_key)) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (po -> type != omapi_type_protocol) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; p = (omapi_protocol_object_t *)po; #ifdef DEBUG_PROTOCOL @@ -836,14 +836,14 @@ isc_result_t omapi_protocol_lookup_auth (omapi_object_t **a, omapi_remote_auth_t *r; if (po -> type != omapi_type_protocol) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; p = (omapi_protocol_object_t *)po; for (r = p -> remote_auth_list; r; r = r -> next) if (r -> remote_handle == handle) return omapi_object_reference (a, r -> a, MDL); - return ISC_R_KEY_UNKNOWN; + return DHCP_R_KEY_UNKNOWN; } isc_result_t omapi_protocol_set_value (omapi_object_t *h, @@ -855,12 +855,12 @@ isc_result_t omapi_protocol_set_value (omapi_object_t *h, omapi_remote_auth_t *r; if (h -> type != omapi_type_protocol) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; p = (omapi_protocol_object_t *)h; if (omapi_ds_strcmp (name, "default-authenticator") == 0) { if (value -> type != omapi_datatype_object) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (!value || !value -> u.object) { p -> default_auth = (omapi_remote_auth_t *)0; @@ -870,7 +870,7 @@ isc_result_t omapi_protocol_set_value (omapi_object_t *h, break; if (!r) - return ISC_R_KEY_UNKNOWN; + return DHCP_R_KEY_UNKNOWN; p -> default_auth = r; } @@ -892,7 +892,7 @@ isc_result_t omapi_protocol_get_value (omapi_object_t *h, omapi_protocol_object_t *p; if (h -> type != omapi_type_protocol) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; p = (omapi_protocol_object_t *)h; if (omapi_ds_strcmp (name, "default-authenticator") == 0) { @@ -914,7 +914,7 @@ isc_result_t omapi_protocol_destroy (omapi_object_t *h, { omapi_protocol_object_t *p; if (h -> type != omapi_type_protocol) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; p = (omapi_protocol_object_t *)h; if (p -> message) omapi_message_dereference (&p -> message, file, line); @@ -944,7 +944,7 @@ isc_result_t omapi_protocol_stuff_values (omapi_object_t *c, omapi_object_t *p) { if (p -> type != omapi_type_protocol) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (p -> inner && p -> inner -> type -> stuff_values) return (*(p -> inner -> type -> stuff_values)) (c, id, @@ -982,7 +982,7 @@ isc_result_t omapi_protocol_configure_security (omapi_object_t *h, h = h -> outer; if (h -> type != omapi_type_protocol_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; l = (omapi_protocol_listener_object_t *)h; l -> verify_auth = verify_auth; @@ -1039,7 +1039,7 @@ isc_result_t omapi_protocol_listener_signal (omapi_object_t *o, omapi_protocol_listener_object_t *p; if (!o || o -> type != omapi_type_protocol_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; p = (omapi_protocol_listener_object_t *)o; /* Not a signal we recognize? */ @@ -1052,7 +1052,7 @@ isc_result_t omapi_protocol_listener_signal (omapi_object_t *o, c = va_arg (ap, omapi_object_t *); if (!c || c -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; obj = (omapi_protocol_object_t *)0; status = omapi_protocol_allocate (&obj, MDL); @@ -1092,7 +1092,7 @@ isc_result_t omapi_protocol_listener_set_value (omapi_object_t *h, omapi_typed_data_t *value) { if (h -> type != omapi_type_protocol_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (h -> inner && h -> inner -> type -> set_value) return (*(h -> inner -> type -> set_value)) @@ -1106,7 +1106,7 @@ isc_result_t omapi_protocol_listener_get_value (omapi_object_t *h, omapi_value_t **value) { if (h -> type != omapi_type_protocol_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (h -> inner && h -> inner -> type -> get_value) return (*(h -> inner -> type -> get_value)) @@ -1118,7 +1118,7 @@ isc_result_t omapi_protocol_listener_destroy (omapi_object_t *h, const char *file, int line) { if (h -> type != omapi_type_protocol_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return ISC_R_SUCCESS; } @@ -1130,7 +1130,7 @@ isc_result_t omapi_protocol_listener_stuff (omapi_object_t *c, omapi_object_t *p) { if (p -> type != omapi_type_protocol_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (p -> inner && p -> inner -> type -> stuff_values) return (*(p -> inner -> type -> stuff_values)) (c, id, @@ -1148,7 +1148,7 @@ isc_result_t omapi_protocol_send_status (omapi_object_t *po, omapi_object_t *mo; if (po -> type != omapi_type_protocol) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; status = omapi_message_new ((omapi_object_t **)&message, MDL); if (status != ISC_R_SUCCESS) @@ -1206,7 +1206,7 @@ isc_result_t omapi_protocol_send_open (omapi_object_t *po, omapi_object_t *mo; if (po -> type != omapi_type_protocol) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; status = omapi_message_new ((omapi_object_t **)&message, MDL); mo = (omapi_object_t *)message; @@ -1265,7 +1265,7 @@ isc_result_t omapi_protocol_send_update (omapi_object_t *po, omapi_object_t *mo; if (po -> type != omapi_type_protocol) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; status = omapi_message_new ((omapi_object_t **)&message, MDL); if (status != ISC_R_SUCCESS) diff --git a/omapip/result.c b/omapip/result.c index 6b682362..383279fb 100644 --- a/omapip/result.c +++ b/omapip/result.c @@ -1,23 +1,21 @@ /* result.c + */ - Cheap knock-off of libisc result table code. This is just a place-holder - until the actual libisc merge. */ - -/* - * Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC") +/* + * Copyright (c) 2004,2007,2009 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1999-2003 by Internet Software Consortium * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or 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. + * 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. * * Internet Systems Consortium, Inc. * 950 Charter Street @@ -25,97 +23,64 @@ * * https://www.isc.org/ * - * This software has been written for Internet Systems Consortium - * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. - * To learn more about Internet Systems Consortium, see - * ``https://www.isc.org/''. To learn more about Vixie Enterprises, - * see ``http://www.vix.com''. To learn more about Nominum, Inc., see - * ``http://www.nominum.com''. */ #include "dhcpd.h" -#include +/* + * In the previous code the results started at 36 + * rather than ISC_RESULTCLASS_DHCP + 0 + * ISC_R_NOTCONNECTED was + 4 (40), it has been superseeded by the isc version + */ -static const char *text[ISC_R_NRESULTS] = { - "success", /* 0 */ - "out of memory", /* 1 */ - "timed out", /* 2 */ - "no available threads", /* 3 */ - "address not available", /* 4 */ - "address in use", /* 5 */ - "permission denied", /* 6 */ - "no pending connections", /* 7 */ - "network unreachable", /* 8 */ - "host unreachable", /* 9 */ - "network down", /* 10 */ - "host down", /* 11 */ - "connection refused", /* 12 */ - "not enough free resources", /* 13 */ - "end of file", /* 14 */ - "socket already bound", /* 15 */ - "task is done", /* 16 */ - "lock busy", /* 17 */ - "already exists", /* 18 */ - "ran out of space", /* 19 */ - "operation canceled", /* 20 */ - "sending events is not allowed", /* 21 */ - "shutting down", /* 22 */ - "not found", /* 23 */ - "unexpected end of input", /* 24 */ - "failure", /* 25 */ - "I/O error", /* 26 */ - "not implemented", /* 27 */ - "unbalanced parentheses", /* 28 */ - "no more", /* 29 */ - "invalid file", /* 30 */ - "bad base64 encoding", /* 31 */ - "unexpected token", /* 32 */ - "quota reached", /* 33 */ - "unexpected error", /* 34 */ - "already running", /* 35 */ - "host unknown", /* 36 */ - "protocol version mismatch", /* 37 */ - "protocol error", /* 38 */ - "invalid argument", /* 39 */ - "not connected", /* 40 */ - "data not yet available", /* 41 */ - "object unchanged", /* 42 */ - "more than one object matches key", /* 43 */ - "key conflict", /* 44 */ - "parse error(s) occurred", /* 45 */ - "no key specified", /* 46 */ - "zone TSIG key not known", /* 47 */ - "invalid TSIG key", /* 48 */ - "operation in progress", /* 49 */ - "DNS format error", /* 50 */ - "DNS server failed", /* 51 */ - "no such domain", /* 52 */ - "not implemented", /* 53 */ - "refused", /* 54 */ - "domain already exists", /* 55 */ - "RRset already exists", /* 56 */ - "no such RRset", /* 57 */ - "not authorized", /* 58 */ - "not a zone", /* 59 */ - "bad DNS signature", /* 60 */ - "bad DNS key", /* 61 */ - "clock skew too great", /* 62 */ - "no root zone", /* 63 */ - "destination address required", /* 64 */ - "cross-zone update", /* 65 */ - "no TSIG signature", /* 66 */ - "not equal", /* 67 */ - "connection reset by peer", /* 68 */ - "unknown attribute" /* 69 */ +static const char *text[DHCP_R_NRESULTS] = { + "host unknown", /* 0 */ + "protocol version mismatch", /* 1 */ + "protocol error", /* 2 */ + "invalid argument", /* 3 */ + "data not yet available", /* 4 */ + "object unchanged", /* 5 */ + "more than one object matches key", /* 6 */ + "key conflict", /* 7 */ + "parse error(s) occurred", /* 8 */ + "no key specified", /* 9 */ + "zone TSIG key not known", /* 10 */ + "invalid TSIG key", /* 11 */ + "operation in progress", /* 12 */ + "DNS format error", /* 13 */ + "DNS server failed", /* 14 */ + "no such domain", /* 15 */ + "not implemented", /* 16 */ + "refused", /* 17 */ + "domain already exists", /* 18 */ + "RRset already exists", /* 19 */ + "no such RRset", /* 20 */ + "not authorized", /* 21 */ + "not a zone", /* 22 */ + "bad DNS signature", /* 23 */ + "bad DNS key", /* 24 */ + "clock skew too great", /* 25 */ + "no root zone", /* 26 */ + "destination address required", /* 27 */ + "cross-zone update", /* 28 */ + "no TSIG signature", /* 29 */ + "not equal", /* 30 */ + "connection reset by peer", /* 31 */ + "unknown attribute" /* 32 */ }; -const char *isc_result_totext (isc_result_t result) -{ - static char ebuf[40]; +#define DHCP_RESULT_RESULTSET 2 +#define DHCP_RESULT_UNAVAILABLESET 3 - if (result >= ISC_R_SUCCESS && result < ISC_R_NRESULTS) - return text [result]; - sprintf(ebuf, "unknown error: %d", result); - return ebuf; +// This is a placeholder as we don't allow for external message catalogs yet +isc_msgcat_t * dhcp_msgcat = NULL; + +isc_result_t +dhcp_result_register(void) { + isc_result_t result; + + result = isc_result_register(ISC_RESULTCLASS_DHCP, DHCP_R_NRESULTS, + text, dhcp_msgcat, DHCP_RESULT_RESULTSET); + + return(result); } diff --git a/omapip/support.c b/omapip/support.c index 2a4e8c75..15eeac04 100644 --- a/omapip/support.c +++ b/omapip/support.c @@ -68,8 +68,6 @@ isc_result_t omapi_init (void) { isc_result_t status; - dst_init(); - /* Register all the standard object types... */ status = omapi_object_type_register (&omapi_type_connection, "connection", @@ -543,7 +541,7 @@ isc_result_t omapi_object_update (omapi_object_t *obj, omapi_object_t *id, int i; if (!src) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (src -> type != omapi_type_generic) return ISC_R_NOTIMPLEMENTED; gsrc = (omapi_generic_object_t *)src; @@ -551,7 +549,7 @@ isc_result_t omapi_object_update (omapi_object_t *obj, omapi_object_t *id, status = omapi_set_value (obj, id, gsrc -> values [i] -> name, gsrc -> values [i] -> value); - if (status != ISC_R_SUCCESS && status != ISC_R_UNCHANGED) + if (status != ISC_R_SUCCESS && status != DHCP_R_UNCHANGED) return status; } if (handle) @@ -845,10 +843,10 @@ isc_result_t omapi_get_int_value (unsigned long *v, omapi_typed_data_t *t) } else if (t -> type == omapi_datatype_string || t -> type == omapi_datatype_data) { if (t -> u.buffer.len != sizeof (rv)) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; memcpy (&rv, t -> u.buffer.value, sizeof rv); *v = ntohl (rv); return ISC_R_SUCCESS; } - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } diff --git a/omapip/test.c b/omapip/test.c index 4bdefdec..ccd3c7a6 100644 --- a/omapip/test.c +++ b/omapip/test.c @@ -37,9 +37,10 @@ #include #include #include -#include +#include #include #include +#include int main (int argc, char **argv) { @@ -47,6 +48,8 @@ int main (int argc, char **argv) omapi_object_t *connection = (omapi_object_t*)0; isc_result_t status; + dhcp_context_create(); + omapi_init (); if (argc > 1 && !strcmp (argv [1], "listen")) { diff --git a/omapip/toisc.c b/omapip/toisc.c index 437816fa..d3dfa8ae 100644 --- a/omapip/toisc.c +++ b/omapip/toisc.c @@ -36,61 +36,10 @@ #include #include "arpa/nameser.h" -#include "minires/minires.h" +#include "minires.h" #include -isc_result_t ns_rcode_to_isc (int nsr) -{ - switch (nsr) { - case ns_r_noerror: - return ISC_R_SUCCESS; - - case ns_r_formerr: - return ISC_R_FORMERR; - - case ns_r_servfail: - return ISC_R_SERVFAIL; - - case ns_r_nxdomain: - return ISC_R_NXDOMAIN; - - case ns_r_notimpl: - return ISC_R_NOTIMPL; - - case ns_r_refused: - return ISC_R_REFUSED; - - case ns_r_yxdomain: - return ISC_R_YXDOMAIN; - - case ns_r_yxrrset: - return ISC_R_YXRRSET; - - case ns_r_nxrrset: - return ISC_R_NXRRSET; - - case ns_r_notauth: - return ISC_R_NOTAUTH; - - case ns_r_notzone: - return ISC_R_NOTZONE; - - case ns_r_badsig: - return ISC_R_BADSIG; - - case ns_r_badkey: - return ISC_R_BADKEY; - - case ns_r_badtime: - return ISC_R_BADTIME; - - default: - ; - } - return ISC_R_UNEXPECTED; -} - isc_result_t uerr2isc (int err) { switch (err) { @@ -113,7 +62,7 @@ isc_result_t uerr2isc (int err) return ISC_R_NOSPACE; case ENOEXEC: - return ISC_R_FORMERR; + return DHCP_R_FORMERR; case ECHILD: return ISC_R_NOTFOUND; @@ -125,16 +74,16 @@ isc_result_t uerr2isc (int err) return ISC_R_NOPERM; case EFAULT: - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; case EEXIST: return ISC_R_EXISTS; case EINVAL: - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; case ENOTTY: - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; case EFBIG: return ISC_R_NOSPACE; @@ -161,13 +110,13 @@ isc_result_t uerr2isc (int err) return ISC_R_INVALIDFILE; case EDESTADDRREQ: - return ISC_R_DESTADDRREQ; + return DHCP_R_DESTADDRREQ; case EMSGSIZE: return ISC_R_NOSPACE; case EPROTOTYPE: - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; case ENOPROTOOPT: return ISC_R_NOTIMPLEMENTED; @@ -203,7 +152,7 @@ isc_result_t uerr2isc (int err) return ISC_R_TIMEDOUT; case ECONNRESET: - return ISC_R_CONNRESET; + return DHCP_R_CONNRESET; case ENOBUFS: return ISC_R_NOSPACE; @@ -241,22 +190,22 @@ isc_result_t uerr2isc (int err) #ifdef ERPCMISMATCH case ERPCMISMATCH: - return ISC_R_VERSIONMISMATCH; + return DHCP_R_VERSIONMISMATCH; #endif #ifdef EPROGMISMATCH case EPROGMISMATCH: - return ISC_R_VERSIONMISMATCH; + return DHCP_R_VERSIONMISMATCH; #endif #ifdef EAUTH case EAUTH: - return ISC_R_NOTAUTH; + return DHCP_R_NOTAUTH; #endif #ifdef ENEEDAUTH case ENEEDAUTH: - return ISC_R_NOTAUTH; + return DHCP_R_NOTAUTH; #endif #ifdef EOVERFLOW @@ -266,54 +215,3 @@ isc_result_t uerr2isc (int err) } return ISC_R_UNEXPECTED; } - -ns_rcode isc_rcode_to_ns (isc_result_t isc) -{ - switch (isc) { - case ISC_R_SUCCESS: - return ns_r_noerror; - - case ISC_R_FORMERR: - return ns_r_formerr; - - case ISC_R_SERVFAIL: - return ns_r_servfail; - - case ISC_R_NXDOMAIN: - return ns_r_nxdomain; - - case ISC_R_NOTIMPL: - return ns_r_notimpl; - - case ISC_R_REFUSED: - return ns_r_refused; - - case ISC_R_YXDOMAIN: - return ns_r_yxdomain; - - case ISC_R_YXRRSET: - return ns_r_yxrrset; - - case ISC_R_NXRRSET: - return ns_r_nxrrset; - - case ISC_R_NOTAUTH: - return ns_r_notauth; - - case ISC_R_NOTZONE: - return ns_r_notzone; - - case ISC_R_BADSIG: - return ns_r_badsig; - - case ISC_R_BADKEY: - return ns_r_badkey; - - case ISC_R_BADTIME: - return ns_r_badtime; - - default: - ; - } - return ns_r_servfail; -} diff --git a/omapip/trace.c b/omapip/trace.c index 26ec08d1..1f521a67 100644 --- a/omapip/trace.c +++ b/omapip/trace.c @@ -137,7 +137,7 @@ isc_result_t trace_begin (const char *filename, if (traceoutfile) { log_error ("%s(%d): trace_begin called twice", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } traceoutfile = open (filename, O_CREAT | O_WRONLY | O_EXCL, 0600); @@ -218,12 +218,12 @@ isc_result_t trace_write_packet_iov (trace_type_t *ttype, if (!ttype) { log_error ("%s(%d): trace_write_packet with null trace type", file ? file : "", line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (!traceoutfile) { log_error ("%s(%d): trace_write_packet with no tracefile.", file ? file : "", line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } /* Compute the total length of the iov. */ @@ -532,7 +532,7 @@ isc_result_t trace_get_next_packet (trace_type_t **ttp, "%ld %ld.", (long int)status, (long int)tracefile_header.phlen); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } /* Swap the packet. */ @@ -547,7 +547,7 @@ isc_result_t trace_get_next_packet (trace_type_t **ttp, else { log_error ("Trace packet with unknown index %ld", (long int)tpkt -> type_index); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } /* If we were just hunting for the time marker, we've found it, @@ -558,7 +558,7 @@ isc_result_t trace_get_next_packet (trace_type_t **ttp, status = fsetpos (traceinfile, &curpos); if (status < 0) { log_error ("fsetpos in tracefile failed: %m"); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } return ISC_R_EXISTS; } @@ -571,7 +571,7 @@ isc_result_t trace_get_next_packet (trace_type_t **ttp, status = fsetpos (traceinfile, &curpos); if (status < 0) { log_error ("fsetpos in tracefile failed: %m"); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } return ISC_R_UNEXPECTEDTOKEN; } @@ -598,7 +598,7 @@ isc_result_t trace_get_next_packet (trace_type_t **ttp, else log_error ("Short read on trace payload: %d %d.", status, paylen); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } /* Store the actual length of the payload. */ @@ -620,7 +620,7 @@ isc_result_t trace_get_packet (trace_type_t **ttp, isc_result_t status; if (!buf || *buf) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; tpkt = dmalloc ((unsigned)tracefile_header.phlen, MDL); if (!tpkt) { @@ -676,7 +676,7 @@ isc_result_t trace_get_file (trace_type_t *ttype, /* Disallow some obvious bogosities. */ if (!buf || !len || *buf) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* Save file position in case of filename mismatch. */ status = fgetpos (traceinfile, &curpos); @@ -705,7 +705,7 @@ isc_result_t trace_get_file (trace_type_t *ttype, log_error ("fsetpos in tracefile failed: %m"); dfree (tpkt, MDL); dfree (*buf, MDL); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } return ISC_R_UNEXPECTEDTOKEN; } diff --git a/relay/Makefile.am b/relay/Makefile.am index ab95e84f..d8757cac 100644 --- a/relay/Makefile.am +++ b/relay/Makefile.am @@ -2,7 +2,8 @@ AM_CPPFLAGS = -DLOCALSTATEDIR='"@localstatedir@"' sbin_PROGRAMS = dhcrelay dhcrelay_SOURCES = dhcrelay.c -dhcrelay_LDADD = ../common/libdhcp.a ../omapip/libomapi.a ../dst/libdst.a ../minires/libres.a +dhcrelay_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \ + ../bind/lib/libdns.a ../bind/lib/libisc.a man_MANS = dhcrelay.8 EXTRA_DIST = $(man_MANS) diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c index 2cfdf29f..0bed393c 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -193,6 +193,12 @@ main(int argc, char **argv) { setlogmask(LOG_UPTO(LOG_INFO)); #endif + /* Set up the isc and dns library managers */ + status = dhcp_context_create(); + if (status != ISC_R_SUCCESS) + log_fatal("Can't initialize context: %s", + isc_result_totext(status)); + /* Set up the OMAPI. */ status = omapi_init(); if (status != ISC_R_SUCCESS) diff --git a/server/Makefile.am b/server/Makefile.am index efd3b048..09af7258 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -7,9 +7,9 @@ dhcpd_SOURCES = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \ dhcpv6.c mdb6.c # libomapi.a this is here twice to handle circular library dependencies :( -dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.a ../dst/libdst.a \ - ../dhcpctl/libdhcpctl.a ../minires/libres.a \ - ../omapip/libomapi.a +dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \ + ../dhcpctl/libdhcpctl.a ../omapip/libomapi.a \ + ../bind/lib/libdns.a ../bind/lib/libisc.a man_MANS = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5 EXTRA_DIST = $(man_MANS) diff --git a/server/confpars.c b/server/confpars.c index 47e2bf45..1b3600a8 100644 --- a/server/confpars.c +++ b/server/confpars.c @@ -245,7 +245,7 @@ isc_result_t conf_file_subparse (struct parse *cfile, struct group *group, } while (1); token = next_token (&val, (unsigned *)0, cfile); - status = cfile -> warnings_occurred ? ISC_R_BADPARSE : ISC_R_SUCCESS; + status = cfile->warnings_occurred ? DHCP_R_BADPARSE : ISC_R_SUCCESS; return status; } @@ -304,7 +304,7 @@ isc_result_t lease_file_subparse (struct parse *cfile) } while (1); - status = cfile -> warnings_occurred ? ISC_R_BADPARSE : ISC_R_SUCCESS; + status = cfile->warnings_occurred ? DHCP_R_BADPARSE : ISC_R_SUCCESS; return status; } diff --git a/server/db.c b/server/db.c index 7e01878b..c20c2600 100644 --- a/server/db.c +++ b/server/db.c @@ -54,7 +54,7 @@ write_binding_scope(FILE *db_file, struct binding *bnd, char *prepend) { char *s; if ((db_file == NULL) || (bnd == NULL) || (prepend == NULL)) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (bnd->value->type == binding_data) { if (bnd->value->value.data.data != NULL) { diff --git a/server/ddns.c b/server/ddns.c index cd8d0aca..53bdb2b2 100644 --- a/server/ddns.c +++ b/server/ddns.c @@ -34,10 +34,16 @@ #include "dhcpd.h" #include "dst/md5.h" -#include "minires/minires.h" +#include #ifdef NSUPDATE +static void ddns_fwd_srv_connector(struct lease *lease, + struct iasubopt *lease6, + struct binding_scope **inscope, + dhcp_ddns_cb_t *ddns_cb, + isc_result_t eresult); + /* DN: No way of checking that there is enough space in a data_string's buffer. Be certain to allocate enough! TL: This is why the expression evaluation code allocates a *new* @@ -51,162 +57,6 @@ static void data_string_append (struct data_string *ds1, ds1 -> len += ds2 -> len; } -static isc_result_t ddns_update_ptr (struct data_string *ddns_fwd_name, - struct data_string *ddns_rev_name, - unsigned long ttl) -{ - ns_updque updqueue; - ns_updrec *updrec; - isc_result_t result = ISC_R_UNEXPECTED; - - /* - * The DHCP server submits a DNS query which deletes all of the PTR RRs - * associated with the lease IP address, and adds a PTR RR whose data - * is the client's (possibly disambiguated) host name. The server also - * adds a DHCID RR specified in Section 4.3. - * -- "Interaction between DHCP and DNS" - */ - - ISC_LIST_INIT (updqueue); - - /* - * Delete all PTR RRs. - */ - updrec = minires_mkupdrec (S_UPDATE, - (const char *)ddns_rev_name -> data, - C_IN, T_PTR, 0); - if (!updrec) { - result = ISC_R_NOMEMORY; - goto error; - } - - updrec -> r_data = (unsigned char *)0; - updrec -> r_size = 0; - updrec -> r_opcode = DELETE; - - ISC_LIST_APPEND (updqueue, updrec, r_link); - - /* - * Add PTR RR. - */ - updrec = minires_mkupdrec (S_UPDATE, - (const char *)ddns_rev_name -> data, - C_IN, T_PTR, ttl); - if (!updrec) { - result = ISC_R_NOMEMORY; - goto error; - } - - updrec -> r_data = ddns_fwd_name -> data; - updrec -> r_size = ddns_fwd_name -> len; - updrec -> r_opcode = ADD; - - ISC_LIST_APPEND (updqueue, updrec, r_link); - - /* - * Attempt to perform the update. - */ - result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue)); -#if defined (DEBUG) - print_dns_status ((int)result, &updqueue); -#endif - if (result == ISC_R_SUCCESS) { - log_info ("added reverse map from %.*s to %.*s", - (int)ddns_rev_name -> len, - (const char *)ddns_rev_name -> data, - (int)ddns_fwd_name -> len, - (const char *)ddns_fwd_name -> data); - } else { - log_error ("unable to add reverse map from %.*s to %.*s: %s", - (int)ddns_rev_name -> len, - (const char *)ddns_rev_name -> data, - (int)ddns_fwd_name -> len, - (const char *)ddns_fwd_name -> data, - isc_result_totext (result)); - } - - /* Fall through. */ - error: - - while (!ISC_LIST_EMPTY (updqueue)) { - updrec = ISC_LIST_HEAD (updqueue); - ISC_LIST_UNLINK (updqueue, updrec, r_link); - minires_freeupdrec (updrec); - } - - return result; -} - - -static isc_result_t ddns_remove_ptr (struct data_string *ddns_rev_name) -{ - ns_updque updqueue; - ns_updrec *updrec; - isc_result_t result; - - /* - * When a lease expires or a DHCP client issues a DHCPRELEASE request, - * the DHCP server SHOULD delete the PTR RR that matches the DHCP - * binding, if one was successfully added. The server's update query - * SHOULD assert that the name in the PTR record matches the name of - * the client whose lease has expired or been released. - * -- "Interaction between DHCP and DNS" - */ - - ISC_LIST_INIT (updqueue); - - /* - * Delete the PTR RRset for the leased address. - */ - updrec = minires_mkupdrec (S_UPDATE, - (const char *)ddns_rev_name -> data, - C_IN, T_PTR, 0); - if (!updrec) { - result = ISC_R_NOMEMORY; - goto error; - } - - updrec -> r_data = (unsigned char *)0; - updrec -> r_size = 0; - updrec -> r_opcode = DELETE; - - ISC_LIST_APPEND (updqueue, updrec, r_link); - - /* - * Attempt to perform the update. - */ - result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue)); -#if defined (DEBUG) - print_dns_status ((int)result, &updqueue); -#endif - if (result == ISC_R_SUCCESS) { - log_info ("removed reverse map on %.*s", - (int)ddns_rev_name -> len, - (const char *)ddns_rev_name -> data); - } else { - if (result != ISC_R_NXRRSET && result != ISC_R_NXDOMAIN) - log_error ("can't remove reverse map on %.*s: %s", - (int)ddns_rev_name -> len, - (const char *)ddns_rev_name -> data, - isc_result_totext (result)); - } - - /* Not there is success. */ - if (result == ISC_R_NXRRSET || result == ISC_R_NXDOMAIN) - result = ISC_R_SUCCESS; - - /* Fall through. */ - error: - - while (!ISC_LIST_EMPTY (updqueue)) { - updrec = ISC_LIST_HEAD (updqueue); - ISC_LIST_UNLINK (updqueue, updrec, r_link); - minires_freeupdrec (updrec); - } - - return result; -} - /* Determine what, if any, forward and reverse updates need to be * performed, and carry them through. @@ -221,44 +71,75 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, struct data_string ddns_domainname; struct data_string old_ddns_fwd_name; struct data_string ddns_fwd_name; - struct data_string ddns_rev_name; + //struct data_string ddns_rev_name; struct data_string ddns_dhcid; - struct binding_scope **scope; - struct iaddr addr; + struct binding_scope **scope = NULL; + //struct iaddr addr; struct data_string d1; struct option_cache *oc; int s1, s2; int result = 0; - isc_result_t rcode1 = ISC_R_SUCCESS, rcode2 = ISC_R_SUCCESS; + isc_result_t rcode1 = ISC_R_SUCCESS; int server_updates_a = 1; - int server_updates_ptr = 1; + //int server_updates_ptr = 1; struct buffer *bp = (struct buffer *)0; int ignorep = 0, client_ignorep = 0; int rev_name_len; int i; + dhcp_ddns_cb_t *ddns_cb; + int do_remove = 0; + if (ddns_update_style != 2) return 0; + /* + * sigh, I want to cancel any previous udpates before we do anything + * else but this means we need to deal with the lease vs lease6 + * question twice. + * If there is a ddns request already outstanding cancel it. + */ + if (lease != NULL) { - scope = &(lease->scope); - addr = lease->ip_addr; + if ((old != NULL) && (old->ddns_cb != NULL)) { + ddns_cancel(old->ddns_cb); + old->ddns_cb = NULL; + } } else if (lease6 != NULL) { - scope = &(lease6->scope); - memcpy(addr.iabuf, lease6->addr.s6_addr, 16); - addr.len = 16; + if ((old6 != NULL) && (old6->ddns_cb != NULL)) { + ddns_cancel(old->ddns_cb); + old6->ddns_cb = NULL; + } } else { log_fatal("Impossible condition at %s:%d.", MDL); /* Silence compiler warnings. */ - return 0; + result = 0; + return(0); } - memset(&d1, 0, sizeof(d1)); + /* allocate our control block */ + ddns_cb = ddns_cb_alloc(MDL); + if (ddns_cb == NULL) { + return(0); + } + /* assume that we shall update both the A and ptr records */ + ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_UPDATE_PTR; + + if (lease != NULL) { + scope = &(lease->scope); + ddns_cb->address = lease->ip_addr; + } else if (lease6 != NULL) { + scope = &(lease6->scope); + memcpy(ddns_cb->address.iabuf, lease6->addr.s6_addr, 16); + ddns_cb->address.len = 16; + } + + memset (&d1, 0, sizeof(d1)); memset (&ddns_hostname, 0, sizeof (ddns_hostname)); memset (&ddns_domainname, 0, sizeof (ddns_domainname)); memset (&old_ddns_fwd_name, 0, sizeof (ddns_fwd_name)); memset (&ddns_fwd_name, 0, sizeof (ddns_fwd_name)); - memset (&ddns_rev_name, 0, sizeof (ddns_rev_name)); + //memset (&ddns_rev_name, 0, sizeof (ddns_rev_name)); memset (&ddns_dhcid, 0, sizeof (ddns_dhcid)); /* If we are allowed to accept the client's update of its own A @@ -288,6 +169,7 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, NULL, packet->options, options, scope, oc, MDL)) goto noclient; + ddns_cb->flags &= ~DDNS_UPDATE_ADDR; server_updates_a = 0; goto client_updates; } @@ -300,7 +182,7 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, !evaluate_boolean_option_cache(&ignorep, packet, lease, NULL, packet->options, options, scope, oc, MDL)) { - return 0; + goto out; } /* If it's a static lease, then don't do the DNS update unless we're @@ -313,7 +195,7 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, !evaluate_boolean_option_cache(&ignorep, packet, lease, NULL, packet->options, options, scope, oc, MDL)) - return 0; + goto out; } /* @@ -346,12 +228,12 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, ddns_hostname.len + ddns_domainname.len + 2, MDL); if (ddns_fwd_name.buffer) { - ddns_fwd_name.data = ddns_fwd_name.buffer -> data; + ddns_fwd_name.data = ddns_fwd_name.buffer->data; data_string_append (&ddns_fwd_name, &ddns_hostname); - ddns_fwd_name.buffer -> data [ddns_fwd_name.len] = '.'; + ddns_fwd_name.buffer->data[ddns_fwd_name.len] = '.'; ddns_fwd_name.len++; data_string_append (&ddns_fwd_name, &ddns_domainname); - ddns_fwd_name.buffer -> data [ddns_fwd_name.len] ='\0'; + ddns_fwd_name.buffer->data[ddns_fwd_name.len] ='\0'; ddns_fwd_name.terminated = 1; } } @@ -363,12 +245,11 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, if (old_ddns_fwd_name.len != ddns_fwd_name.len || memcmp (old_ddns_fwd_name.data, ddns_fwd_name.data, old_ddns_fwd_name.len)) { - /* If the name is different, try to delete - the old A record. */ - if (!ddns_removals(lease, lease6)) - goto out; - /* If the delete succeeded, go install the new - record. */ + /* + * If the name is different, mark the old record + * for deletion and continue getting the new info. + */ + do_remove = 1; goto in; } @@ -432,11 +313,16 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, /* If we don't have a name that the client has been assigned, we can just skip all this. */ - if (!ddns_fwd_name.len) - goto out; - if (ddns_fwd_name.len > 255) { - log_error ("client provided fqdn: too long"); + if ((!ddns_fwd_name.len) || (ddns_fwd_name.len > 255)) { + if (ddns_fwd_name.len > 255) { + log_error ("client provided fqdn: too long"); + } + + /* If desired do the removals */ + if (do_remove != 0) { + (void) ddns_removals(lease, lease6, NULL); + } goto out; } @@ -449,7 +335,7 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, packet->options, options, scope, oc, MDL)) { if (d1.len == sizeof (u_int32_t)) - ddns_ttl = getULong (d1.data); + ddns_cb->ttl = getULong (d1.data); data_string_forget (&d1, MDL); } } @@ -469,14 +355,14 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, * Figure out the length of the part of the name that depends * on the address. */ - if (addr.len == 4) { + if (ddns_cb->address.len == 4) { char buf[17]; /* XXX: WOW this is gross. */ rev_name_len = snprintf(buf, sizeof(buf), "%u.%u.%u.%u.", - addr.iabuf[3] & 0xff, - addr.iabuf[2] & 0xff, - addr.iabuf[1] & 0xff, - addr.iabuf[0] & 0xff) + 1; + ddns_cb->address.iabuf[3] & 0xff, + ddns_cb->address.iabuf[2] & 0xff, + ddns_cb->address.iabuf[1] & 0xff, + ddns_cb->address.iabuf[0] & 0xff) + 1; if (s1) { rev_name_len += d1.len; @@ -488,7 +374,7 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, data_string_forget(&d1, MDL); } } - } else if (addr.len == 16) { + } else if (ddns_cb->address.len == 16) { /* * IPv6 reverse names are always the same length, with * 32 hex characters separated by dots. @@ -502,7 +388,7 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, /* Set s1 to make sure we gate into updates. */ s1 = 1; } else { - log_fatal("invalid address length %d", addr.len); + log_fatal("invalid address length %d", ddns_cb->address.len); /* Silence compiler warnings. */ return 0; } @@ -513,33 +399,33 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, !evaluate_boolean_option_cache(&ignorep, packet, lease, NULL, packet->options, options, scope, oc, MDL)) { - server_updates_ptr = 0; + ddns_cb->flags &= ~DDNS_UPDATE_PTR; } if (s1) { - buffer_allocate(&ddns_rev_name.buffer, rev_name_len, MDL); - if (ddns_rev_name.buffer != NULL) { - ddns_rev_name.data = ddns_rev_name.buffer->data; + buffer_allocate(&ddns_cb->rev_name.buffer, rev_name_len, MDL); + if (ddns_cb->rev_name.buffer != NULL) { + struct data_string *rname = &ddns_cb->rev_name; + rname->data = rname->buffer->data; - if (addr.len == 4) { - ddns_rev_name.len = - sprintf((char *)ddns_rev_name.buffer->data, + if (ddns_cb->address.len == 4) { + rname->len = + sprintf((char *)rname->buffer->data, "%u.%u.%u.%u.", - addr.iabuf[3] & 0xff, - addr.iabuf[2] & 0xff, - addr.iabuf[1] & 0xff, - addr.iabuf[0] & 0xff); + ddns_cb->address.iabuf[3] & 0xff, + ddns_cb->address.iabuf[2] & 0xff, + ddns_cb->address.iabuf[1] & 0xff, + ddns_cb->address.iabuf[0] & 0xff); /* * d1.data may be opaque, garbage bytes, from * user (mis)configuration. */ - data_string_append(&ddns_rev_name, &d1); - ddns_rev_name.buffer->data[ddns_rev_name.len] = - '\0'; - } else if (addr.len == 16) { - char *p = (char *)&ddns_rev_name.buffer->data; - unsigned char *a = addr.iabuf + 15; + data_string_append(rname, &d1); + rname->buffer->data[rname->len] = '\0'; + } else if (ddns_cb->address.len == 16) { + char *p = (char *)&rname->buffer->data; + unsigned char *a = ddns_cb->address.iabuf + 15; for (i=0; i<16; i++) { sprintf(p, "%x.%x.", (*a & 0xF), ((*a >> 4) & 0xF)); @@ -547,11 +433,10 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, a -= 1; } strcat(p, "ip6.arpa."); - ddns_rev_name.len = - strlen((const char *)ddns_rev_name.data); + rname->len = strlen((const char *)rname->data); } - ddns_rev_name.terminated = 1; + rname->terminated = 1; } if (d1.data != NULL) @@ -561,19 +446,18 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, /* * If we are updating the A record, compute the DHCID value. */ - if (server_updates_a) { - memset (&ddns_dhcid, 0, sizeof ddns_dhcid); + if ((ddns_cb->flags & DDNS_UPDATE_ADDR) != 0) { if (lease6 != NULL) - result = get_dhcid(&ddns_dhcid, 2, + result = get_dhcid(&ddns_cb->dhcid, 2, lease6->ia->iaid_duid.data, lease6->ia->iaid_duid.len); else if ((lease != NULL) && (lease->uid != NULL) && (lease->uid_len != 0)) - result = get_dhcid (&ddns_dhcid, + result = get_dhcid (&ddns_cb->dhcid, DHO_DHCP_CLIENT_IDENTIFIER, lease -> uid, lease -> uid_len); else if (lease != NULL) - result = get_dhcid (&ddns_dhcid, 0, + result = get_dhcid (&ddns_cb->dhcid, 0, lease -> hardware_addr.hbuf, lease -> hardware_addr.hlen); else @@ -584,54 +468,36 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, } /* - * Start the resolver, if necessary. + * Perform updates. */ - if (!resolver_inited) { - minires_ninit (&resolver_state); - resolver_inited = 1; - resolver_state.retrans = 1; - resolver_state.retry = 1; + + data_string_copy(&ddns_cb->fwd_name, &ddns_fwd_name, MDL); + + if (ddns_cb->flags && DDNS_UPDATE_ADDR) { + oc = lookup_option(&server_universe, options, + SV_DDNS_CONFLICT_DETECT); + if (oc && + !evaluate_boolean_option_cache(&ignorep, packet, lease, + NULL, packet->options, + options, scope, oc, MDL)) + ddns_cb->flags |= DDNS_CONFLICT_OVERRIDE; + } /* - * Perform updates. + * Previously if we failed during the removal operations + * we skipped the fqdn option processing. I'm not sure + * if we want to continue with that if we fail before sending + * the ddns messages. Currently we don't. */ - if (ddns_fwd_name.len && ddns_dhcid.len) { - unsigned conflict; - - oc = lookup_option(&server_universe, options, - SV_DDNS_CONFLICT_DETECT); - if (!oc || - evaluate_boolean_option_cache(&ignorep, packet, lease, - NULL, packet->options, - options, scope, oc, MDL)) - conflict = 1; - else - conflict = 0; - - rcode1 = ddns_update_fwd(&ddns_fwd_name, addr, &ddns_dhcid, - ddns_ttl, 0, conflict); + if (do_remove) { + rcode1 = ddns_removals(lease, lease6, ddns_cb); } - - if (rcode1 == ISC_R_SUCCESS && server_updates_ptr) { - if (ddns_fwd_name.len && ddns_rev_name.len) - rcode2 = ddns_update_ptr (&ddns_fwd_name, - &ddns_rev_name, ddns_ttl); - } else - rcode2 = rcode1; - - if (rcode1 == ISC_R_SUCCESS && - (server_updates_a || rcode2 == ISC_R_SUCCESS)) { - bind_ds_value(scope, server_updates_a ? "ddns-fwd-name" - : "ddns-client-fqdn", - &ddns_fwd_name); - if (server_updates_a) - bind_ds_value(scope, "ddns-txt", &ddns_dhcid); - } - - if (rcode2 == ISC_R_SUCCESS && server_updates_ptr) { - bind_ds_value(scope, "ddns-rev-name", &ddns_rev_name); + else { + ddns_fwd_srv_connector(lease, lease6, scope, ddns_cb, + ISC_R_SUCCESS); } + ddns_cb = NULL; noerror: /* @@ -760,12 +626,12 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, bp, &bp->data [2], 1, FQDN_ENCODED, 0)) goto badfqdn; - bp -> data [3] = isc_rcode_to_ns (rcode1); + bp -> data [3] = 255;//isc_rcode_to_ns (rcode1); if (!save_option_buffer(&fqdn_universe, options, bp, &bp->data [3], 1, FQDN_RCODE1, 0)) goto badfqdn; - bp -> data [4] = isc_rcode_to_ns (rcode2); + bp -> data [4] = 255;//isc_rcode_to_ns (rcode2); if (!save_option_buffer(&fqdn_universe, options, bp, &bp->data [4], 1, FQDN_RCODE2, 0)) @@ -786,119 +652,850 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, /* * Final cleanup. */ + if (ddns_cb != NULL) { + ddns_cb_free(ddns_cb, MDL); + } + data_string_forget(&d1, MDL); data_string_forget(&ddns_hostname, MDL); data_string_forget(&ddns_domainname, MDL); data_string_forget(&old_ddns_fwd_name, MDL); data_string_forget(&ddns_fwd_name, MDL); - data_string_forget(&ddns_rev_name, MDL); - data_string_forget(&ddns_dhcid, MDL); + //data_string_forget(&ddns_rev_name, MDL); + //data_string_forget(&ddns_dhcid, MDL); if (bp) buffer_dereference(&bp, MDL); return result; } -/* Remove relevant entries from DNS. */ -int -ddns_removals(struct lease *lease, struct iasubopt *lease6) -{ - struct data_string ddns_fwd_name; - struct data_string ddns_rev_name; - struct data_string ddns_dhcid; - isc_result_t rcode; - struct binding_scope **scope; - struct iaddr addr; - int result = 0; - int client_updated = 0; +/* + * Utility function to update text strings within a lease. + * + * The first issue is to find the proper scope. Sometimes we shall be + * called with a pointer to the scope in other cases we need to find + * the proper lease and then get the scope. Once we have the scope we update + * the proper strings, as indicated by the state value in the control block. + * Lastly, if we needed to find the scope we write it out, if we used a + * scope that was passed as an argument we don't write it, assuming that + * our caller (or his ...) will do the write. + */ +isc_result_t +ddns_update_lease_text(dhcp_ddns_cb_t *ddns_cb, + struct binding_scope **inscope) +{ + struct binding_scope **scope = NULL; + struct lease *lease = NULL; + struct iasubopt *lease6 = NULL; + struct ipv6_pool *pool = NULL; + struct in6_addr addr; + struct data_string lease_dhcid; + + if (inscope != NULL) { + scope = inscope; + } else if (ddns_cb->address.len == 4) { + if (find_lease_by_ip_addr(&lease, ddns_cb->address, MDL) != 0){ + scope = &(lease->scope); + } + } else if (ddns_cb->address.len == 16) { + memcpy(&addr, &ddns_cb->address.iabuf, 16); + if ((find_ipv6_pool(&pool, D6O_IA_TA, &addr) == + ISC_R_SUCCESS) || + (find_ipv6_pool(&pool, D6O_IA_NA, &addr) == + ISC_R_SUCCESS)) { + if (iasubopt_hash_lookup(&lease6, pool->leases, + &addr, 16, MDL)) { + scope = &(lease6->scope); + } + ipv6_pool_dereference(&pool, MDL); + } + } else { + log_fatal("Impossible condition at %s:%d.", MDL); + } + + if (scope == NULL) { + /* If necessary get rid of the lease */ + if (lease) { + lease_dereference(&lease, MDL); + } + else if (lease6) { + iasubopt_dereference(&lease6, MDL); + } + + return(ISC_R_FAILURE); + } + + /* We now have a scope and can proceed to update it */ + switch(ddns_cb->state) { + case DDNS_STATE_REM_PTR: + unset(*scope, "ddns-rev-name"); + if ((ddns_cb->flags & DDNS_CLIENT_DID_UPDATE) != 0) { + unset(*scope, "ddns-client-fqdn"); + } + break; + + case DDNS_STATE_ADD_PTR: + case DDNS_STATE_CLEANUP: + bind_ds_value(scope, "ddns-rev-name", &ddns_cb->rev_name); + if ((ddns_cb->flags & DDNS_UPDATE_ADDR) == 0) { + bind_ds_value(scope, "ddns-client-fqdn", + &ddns_cb->fwd_name); + } + break; + + case DDNS_STATE_ADD_FW_YXDHCID: + case DDNS_STATE_ADD_FW_NXDOMAIN: + bind_ds_value(scope, "ddns-fwd-name", &ddns_cb->fwd_name); + + /* convert from dns version to lease version of dhcid */ + memset(&lease_dhcid, 0, sizeof(lease_dhcid)); + dhcid_tolease(&ddns_cb->dhcid, &lease_dhcid); + bind_ds_value(scope, "ddns-txt", &lease_dhcid); + data_string_forget(&lease_dhcid, MDL); + + break; + + case DDNS_STATE_REM_FW_NXRR: + case DDNS_STATE_REM_FW_YXDHCID: + unset(*scope, "ddns-fwd-name"); + unset(*scope, "ddns-txt"); + break; + } + + /* If necessary write it out and get rid of the lease */ + if (lease) { + write_lease(lease); + lease_dereference(&lease, MDL); + } else if (lease6) { + write_ia(lease6->ia); + iasubopt_dereference(&lease6, MDL); + } + + return(ISC_R_SUCCESS); +} + + +#if 0 +isc_result_t +ddns_get_lease(dhcp_ddns_cb_t *ddns_cb) +{ + isc_result_t result = ISC_R_FAILURE; + + if (ddns_cb->address.len == 4) { + struct lease **lease = (struct lease **)(&(ddns_cb->lease)); + if (find_lease_by_ip_addr(lease, ddns_cb->address, MDL) != 0) { + ddns_cb->scope = &((*lease)->scope); + result = ISC_R_SUCCESS; + } + } + else if (ddns_cb->address.len == 16) { + struct ipv6_pool *pool = NULL; + struct iasubopt **lease = (struct iasubopt **)(&(ddns_cb->lease)); + struct in6_addr addr; + + memcpy(&addr, &ddns_cb->address.iabuf, 16); + if ((find_ipv6_pool(&pool, D6O_IA_TA, &addr) != + ISC_R_SUCCESS) && + (find_ipv6_pool(&pool, D6O_IA_NA, &addr) != + ISC_R_SUCCESS)) { + return(ISC_R_FAILURE); + } + + if (iasubopt_hash_lookup(lease, pool->leases, + &addr, 16, MDL)) { + ddns_cb->scope = &((*lease)->scope); + result = ISC_R_SUCCESS; + } + ipv6_pool_dereference(&pool, MDL); + } + else { + log_fatal("Impossible condition at %s:%d.", MDL); + } + + return(result); +} + +isc_result_t +ddns_write_lease(dhcp_ddns_cb_t *ddns_cb) +{ + + if (ddns_cb->address.len == 4) { + struct lease **lease = (struct lease **)(&(ddns_cb->lease)); + + write_lease(*lease); + ddns_cb->scope = NULL; + lease_dereference(lease, MDL); + } + else if (ddns_cb->address.len == 16) { + struct iasubopt **lease = (struct iasubopt **)(&(ddns_cb->lease)); + /*sar*/ + /* Hmmm, this seems to be what we do elsewhere, but I'm + not sure this is writing the scope info */ + write_ia((*lease)->ia); + ddns_cb->scope = NULL; + iasubopt_dereference(lease, MDL); + } + else { + log_fatal("Impossible condition at %s:%d.", MDL); + } + + return(ISC_R_SUCCESS); +} +#endif + +/* + * Utility function to update the pointer to the DDNS control block + * in a lease. + * SUCCESS - able to update the pointer + * FAILURE - lease didn't exist or sanity checks failed + * lease and lease6 may be empty in which case we attempt to find + * the lease from the ddns_cb information. + * ddns_cb is the control block to use if a lookup is necessary + * ddns_cb_set is the pointer to insert into the lease and may be NULL + * The last two arguments may look odd as they will be the same much of the + * time, but I need an argument to tell me if I'm setting or clearing in + * addition to the address information from the cb to look up the lease. + * using the same value twice allows me more flexibility. + */ + +isc_result_t +ddns_update_lease_ptr(struct lease *lease, + struct iasubopt *lease6, + dhcp_ddns_cb_t *ddns_cb, + dhcp_ddns_cb_t *ddns_cb_set) +{ + if (lease != NULL) { + lease->ddns_cb = ddns_cb_set; + } else if (lease6 != NULL) { + lease6->ddns_cb = ddns_cb_set; + } else if (ddns_cb->address.len == 4) { + struct lease *find_lease = NULL; + if (find_lease_by_ip_addr(&find_lease, + ddns_cb->address, MDL) != 0) { + find_lease->ddns_cb = ddns_cb_set; + lease_dereference(&find_lease, MDL); + } + else { + return(ISC_R_FAILURE); + } + } else if (ddns_cb->address.len == 16) { + struct iasubopt *find_lease6 = NULL; + struct ipv6_pool *pool = NULL; + struct in6_addr addr; + + memcpy(&addr, &ddns_cb->address.iabuf, 16); + if ((find_ipv6_pool(&pool, D6O_IA_TA, &addr) != + ISC_R_SUCCESS) && + (find_ipv6_pool(&pool, D6O_IA_NA, &addr) != + ISC_R_SUCCESS)) { + return(ISC_R_FAILURE); + } + + if (iasubopt_hash_lookup(&find_lease6, pool->leases, + &addr, 16, MDL)) { + find_lease6->ddns_cb = ddns_cb_set; + iasubopt_dereference(&find_lease6, MDL); + } else { + return(ISC_R_FAILURE); + } + ipv6_pool_dereference(&pool, MDL); + } else { + /* shouldn't get here */ + log_fatal("Impossible condition at %s:%d.", MDL); + } + + return(ISC_R_SUCCESS); +} + +void +ddns_ptr_add(dhcp_ddns_cb_t *ddns_cb, + isc_result_t eresult) +{ + if (eresult == ISC_R_SUCCESS) { + log_info("added reverse map from %.*s to %.*s", + (int)ddns_cb->rev_name.len, + (const char *)ddns_cb->rev_name.data, + (int)ddns_cb->fwd_name.len, + (const char *)ddns_cb->fwd_name.data); + + ddns_update_lease_text(ddns_cb, NULL); + } else { + log_error("unable to add reverse map from %.*s to %.*s: %s", + (int)ddns_cb->rev_name.len, + (const char *)ddns_cb->rev_name.data, + (int)ddns_cb->fwd_name.len, + (const char *)ddns_cb->fwd_name.data, + isc_result_totext (eresult)); + } + + ddns_update_lease_ptr(NULL, NULL, ddns_cb, NULL); + ddns_cb_free(ddns_cb, MDL); + /* + * A single DDNS operation may require several calls depending on + * the current state as the prerequisites for the first message + * may not succeed requiring a second operation and potentially + * a ptr operation after that. The commit_leases operation is + * invoked at the end of this set of operations in order to require + * a single write for all of the changes. We call commit_leases + * here rather than immediately after the call to update the lease + * text in order to save any previously written data. + */ + commit_leases(); + return; +} + +/* + * action routine when trying to remove a pointer + * this will be called after the ddns queries have completed + * if we succeeded in removing the pointer we go to the next step (if any) + * if not we cleanup and leave. + */ + +void +ddns_ptr_remove(dhcp_ddns_cb_t *ddns_cb, + isc_result_t eresult) +{ + isc_result_t result = eresult; + + switch(eresult) { + case ISC_R_SUCCESS: + log_info("removed reverse map on %.*s", + (int)ddns_cb->rev_name.len, + (const char *)ddns_cb->rev_name.data); + /* fall through */ + case DNS_R_NXRRSET: + case DNS_R_NXDOMAIN: + /* No entry is the same as success. + * Remove the information from the lease and + * continue with any next step */ + ddns_update_lease_text(ddns_cb, NULL); + + /* trigger any add operation */ + result = ISC_R_SUCCESS; + break; + + default: + log_error("can't remove reverse map on %.*s: %s", + (int)ddns_cb->rev_name.len, + (const char *)ddns_cb->rev_name.data, + isc_result_totext (eresult)); + break; + } + + ddns_update_lease_ptr(NULL, NULL, ddns_cb, NULL); + ddns_fwd_srv_connector(NULL, NULL, NULL, ddns_cb->next_op, result); + ddns_cb_free(ddns_cb, MDL); + return; +} + + +/* + * If the first query succeeds, the updater can conclude that it + * has added a new name whose only RRs are the A and DHCID RR records. + * The A RR update is now complete (and a client updater is finished, + * while a server might proceed to perform a PTR RR update). + * -- "Interaction between DHCP and DNS" + * + * If the second query succeeds, the updater can conclude that the current + * client was the last client associated with the domain name, and that + * the name now contains the updated A RR. The A RR update is now + * complete (and a client updater is finished, while a server would + * then proceed to perform a PTR RR update). + * -- "Interaction between DHCP and DNS" + * + * If the second query fails with NXRRSET, the updater must conclude + * that the client's desired name is in use by another host. At this + * juncture, the updater can decide (based on some administrative + * configuration outside of the scope of this document) whether to let + * the existing owner of the name keep that name, and to (possibly) + * perform some name disambiguation operation on behalf of the current + * client, or to replace the RRs on the name with RRs that represent + * the current client. If the configured policy allows replacement of + * existing records, the updater submits a query that deletes the + * existing A RR and the existing DHCID RR, adding A and DHCID RRs that + * represent the IP address and client-identity of the new client. + * -- "Interaction between DHCP and DNS" + */ + +void +ddns_fwd_srv_add2(dhcp_ddns_cb_t *ddns_cb, + isc_result_t eresult) +{ + isc_result_t result; + const char *logstr = NULL; + char ddns_address[ + sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; + + /* Construct a printable form of the address for logging */ + strcpy(ddns_address, piaddr(ddns_cb->address)); + + switch(eresult) { + case ISC_R_SUCCESS: + log_info("Added new forward map from %.*s to %s", + (int)ddns_cb->fwd_name.len, + (const char *)ddns_cb->fwd_name.data, + ddns_address); + + ddns_update_lease_text(ddns_cb, NULL); + + if ((ddns_cb->flags & DDNS_UPDATE_PTR) != 0) { + /* if we have zone information get rid of it */ + if (ddns_cb->zone != NULL) { + ddns_cb_forget_zone(ddns_cb); + } + + ddns_cb->state = DDNS_STATE_ADD_PTR; + ddns_cb->cur_func = ddns_ptr_add; + + result = ddns_modify_ptr(ddns_cb); + if (result == ISC_R_SUCCESS) { + return; + } + } + break; + + case DNS_R_YXRRSET: + case DNS_R_YXDOMAIN: + logstr = "DHCID mismatch, belongs to another client."; + break; + + case DNS_R_NXRRSET: + case DNS_R_NXDOMAIN: + logstr = "Has an address record but no DHCID, not mine."; + break; + + default: + logstr = isc_result_totext(eresult); + break; + } + + if (logstr != NULL) { + log_error("Forward map from %.*s to %s FAILED: %s", + (int)ddns_cb->fwd_name.len, + (const char *)ddns_cb->fwd_name.data, + ddns_address, logstr); + } + + ddns_update_lease_ptr(NULL, NULL, ddns_cb, NULL); + ddns_cb_free(ddns_cb, MDL); + /* + * A single DDNS operation may require several calls depending on + * the current state as the prerequisites for the first message + * may not succeed requiring a second operation and potentially + * a ptr operation after that. The commit_leases operation is + * invoked at the end of this set of operations in order to require + * a single write for all of the changes. We call commit_leases + * here rather than immediately after the call to update the lease + * text in order to save any previously written data. + */ + commit_leases(); + return; +} + +void +ddns_fwd_srv_add1(dhcp_ddns_cb_t *ddns_cb, + isc_result_t eresult) +{ + isc_result_t result; + char ddns_address[ + sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; + + /* Construct a printable form of the address for logging */ + strcpy(ddns_address, piaddr(ddns_cb->address)); + + switch(eresult) { + case ISC_R_SUCCESS: + log_info ("Added new forward map from %.*s to %s", + (int)ddns_cb->fwd_name.len, + (const char *)ddns_cb->fwd_name.data, + ddns_address); + + ddns_update_lease_text(ddns_cb, NULL); + + if ((ddns_cb->flags & DDNS_UPDATE_PTR) != 0) { + /* if we have zone information get rid of it */ + if (ddns_cb->zone != NULL) { + ddns_cb_forget_zone(ddns_cb); + } + + ddns_cb->state = DDNS_STATE_ADD_PTR; + ddns_cb->cur_func = ddns_ptr_add; + + result = ddns_modify_ptr(ddns_cb); + if (result == ISC_R_SUCCESS) { + return; + } + } + + break; + + case DNS_R_YXDOMAIN: + /* we can reuse the zone information */ + ddns_cb->state = DDNS_STATE_ADD_FW_YXDHCID; + ddns_cb->cur_func = ddns_fwd_srv_add2; + + result = ddns_modify_fwd(ddns_cb); + if (result == ISC_R_SUCCESS) { + return; + } + + break; + + default: + log_error ("Unable to add forward map from %.*s to %s: %s", + (int)ddns_cb->fwd_name.len, + (const char *)ddns_cb->fwd_name.data, + ddns_address, + isc_result_totext (eresult)); + break; + } + + ddns_update_lease_ptr(NULL, NULL, ddns_cb, NULL); + ddns_cb_free(ddns_cb, MDL); + /* + * A single DDNS operation may require several calls depending on + * the current state as the prerequisites for the first message + * may not succeed requiring a second operation and potentially + * a ptr operation after that. The commit_leases operation is + * invoked at the end of this set of operations in order to require + * a single write for all of the changes. We call commit_leases + * here rather than immediately after the call to update the lease + * text in order to save any previously written data. + */ + commit_leases(); + return; +} + +static void +ddns_fwd_srv_connector(struct lease *lease, + struct iasubopt *lease6, + struct binding_scope **inscope, + dhcp_ddns_cb_t *ddns_cb, + isc_result_t eresult) +{ + isc_result_t result = ISC_R_FAILURE; + + if (ddns_cb == NULL) { + /* nothing to do */ + return; + } + + if (eresult == ISC_R_SUCCESS) { + /* + * If we have updates dispatch as appropriate, + * if not do FQDN binding if desired. + */ + + if (ddns_cb->flags & DDNS_UPDATE_ADDR) { + ddns_cb->state = DDNS_STATE_ADD_FW_NXDOMAIN; + ddns_cb->cur_func = ddns_fwd_srv_add1; + result = ddns_modify_fwd(ddns_cb); + } else if ((ddns_cb->flags & DDNS_UPDATE_PTR) && + (ddns_cb->rev_name.len != 0)) { + ddns_cb->state = DDNS_STATE_ADD_PTR; + ddns_cb->cur_func = ddns_ptr_add; + result = ddns_modify_ptr(ddns_cb); + } else { + ddns_update_lease_text(ddns_cb, inscope); + } + } + + if (result == ISC_R_SUCCESS) { + ddns_update_lease_ptr(lease, lease6, ddns_cb, ddns_cb); + } else { + ddns_cb_free(ddns_cb, MDL); + } + + return; +} + +/* + * If the first query fails, the updater MUST NOT delete the DNS name. It + * may be that the host whose lease on the server has expired has moved + * to another network and obtained a lease from a different server, + * which has caused the client's A RR to be replaced. It may also be + * that some other client has been configured with a name that matches + * the name of the DHCP client, and the policy was that the last client + * to specify the name would get the name. In this case, the DHCID RR + * will no longer match the updater's notion of the client-identity of + * the host pointed to by the DNS name. + * -- "Interaction between DHCP and DNS" + */ + +void +ddns_fwd_srv_rem2(dhcp_ddns_cb_t *ddns_cb, + isc_result_t eresult) +{ + if (eresult == ISC_R_SUCCESS) { + ddns_update_lease_text(ddns_cb, NULL); + + /* Do the next operation */ + if ((ddns_cb->flags & DDNS_UPDATE_PTR) != 0) { + /* if we have zone information get rid of it */ + if (ddns_cb->zone != NULL) { + ddns_cb_forget_zone(ddns_cb); + } + + ddns_cb->state = DDNS_STATE_REM_PTR; + ddns_cb->cur_func = ddns_ptr_remove; + + eresult = ddns_modify_ptr(ddns_cb); + if (eresult == ISC_R_SUCCESS) { + return; + } + } + } + + ddns_update_lease_ptr(NULL, NULL, ddns_cb, NULL); + ddns_fwd_srv_connector(NULL, NULL, NULL, ddns_cb->next_op, eresult); + ddns_cb_free(ddns_cb, MDL); + return; +} + + +/* + * First action routine when trying to remove a fwd + * this will be called after the ddns queries have completed + * if we succeeded in removing the fwd we go to the next step (if any) + * if not we cleanup and leave. + */ + +void +ddns_fwd_srv_rem1(dhcp_ddns_cb_t *ddns_cb, + isc_result_t eresult) +{ + isc_result_t result = eresult; + + switch(eresult) { + case ISC_R_SUCCESS: + /* Do the second step of the FWD removal */ + ddns_cb->state = DDNS_STATE_REM_FW_NXRR; + ddns_cb->cur_func = ddns_fwd_srv_rem2; + result = ddns_modify_fwd(ddns_cb); + if (result == ISC_R_SUCCESS) { + return; + } + break; + + case DNS_R_NXRRSET: + case DNS_R_NXDOMAIN: + ddns_update_lease_text(ddns_cb, NULL); + + /* Do the next operation */ + if ((ddns_cb->flags & DDNS_UPDATE_PTR) != 0) { + /* if we have zone information get rid of it */ + if (ddns_cb->zone != NULL) { + ddns_cb_forget_zone(ddns_cb); + } + + ddns_cb->state = DDNS_STATE_REM_PTR; + ddns_cb->cur_func = ddns_ptr_remove; + + result = ddns_modify_ptr(ddns_cb); + if (result == ISC_R_SUCCESS) { + return; + } + } + else { + /* Trigger the add operation */ + eresult = ISC_R_SUCCESS; + } + break; + + default: + break; + } + + ddns_update_lease_ptr(NULL, NULL, ddns_cb, NULL); + ddns_fwd_srv_connector(NULL, NULL, NULL, ddns_cb->next_op, eresult); + ddns_cb_free(ddns_cb, MDL); +} + + +/* + * Remove relevant entries from DNS. + * + * Return values: + * 0 - badness occurred and we weren't able to do what was wanted + * 1 - we were able to do stuff but it's in progress + * in both cases any additional block has been passed on to it's handler + */ + +int +ddns_removals(struct lease *lease, + struct iasubopt *lease6, + dhcp_ddns_cb_t *add_ddns_cb) +{ + isc_result_t rcode, execute_add = ISC_R_FAILURE; + struct binding_scope **scope = NULL; + int result = 0; + dhcp_ddns_cb_t *ddns_cb; + struct data_string leaseid; + + /* allocate our control block */ + ddns_cb = ddns_cb_alloc(MDL); + if (ddns_cb == NULL) { + goto cleanup; + } + if (lease != NULL) { scope = &(lease->scope); - addr = lease->ip_addr; + ddns_cb->address = lease->ip_addr; } else if (lease6 != NULL) { scope = &(lease6->scope); - memcpy(addr.iabuf, lease6->addr.s6_addr, 16); - addr.len = 16; + memcpy(&ddns_cb->address.iabuf, lease6->addr.s6_addr, 16); + ddns_cb->address.len = 16; } else - return 0; + goto cleanup; /* No scope implies that DDNS has not been performed for this lease. */ if (*scope == NULL) - return 0; + goto cleanup; if (ddns_update_style != 2) - return 0; + goto cleanup; + + /* Assume that we are removing both records */ + ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_UPDATE_PTR; + + /* and that we want to do the add call */ + execute_add = ISC_R_SUCCESS; /* * Look up stored names. */ - memset (&ddns_fwd_name, 0, sizeof (ddns_fwd_name)); - memset (&ddns_rev_name, 0, sizeof (ddns_rev_name)); - memset (&ddns_dhcid, 0, sizeof (ddns_dhcid)); /* - * Start the resolver, if necessary. + * Find the fwd name and copy it to the control block. If we don't + * have it we can't delete the fwd record but we can still try to + * remove the ptr record and cleanup the lease information if the + * client did the fwd update. */ - if (!resolver_inited) { - minires_ninit (&resolver_state); - resolver_inited = 1; - resolver_state.retrans = 1; - resolver_state.retry = 1; - } + if (!find_bound_string(&ddns_cb->fwd_name, *scope, "ddns-fwd-name")) { + /* don't try and delete the A, or do the add */ + ddns_cb->flags &= ~DDNS_UPDATE_ADDR; + execute_add = ISC_R_FAILURE; - /* We need the fwd name whether we are deleting both records or just - the PTR record, so if it's not there, we can't proceed. */ - if (!find_bound_string(&ddns_fwd_name, *scope, "ddns-fwd-name")) { - /* If there's no ddns-fwd-name, look for the client fqdn, - in case the client did the update. */ - if (find_bound_string(&ddns_fwd_name, *scope, - "ddns-client-fqdn")) - client_updated = 1; - goto try_rev; - } - - /* If the ddns-txt binding isn't there, this isn't an interim - or rfc3??? record, so we can't delete the A record using - this mechanism, but we can delete the PTR record. */ - if (!find_bound_string (&ddns_dhcid, *scope, "ddns-txt")) { - result = 1; - goto try_rev; - } - - /* - * Perform removals. - */ - if (ddns_fwd_name.len) - rcode = ddns_remove_fwd(&ddns_fwd_name, addr, &ddns_dhcid); - else - rcode = ISC_R_SUCCESS; - - if (rcode == ISC_R_SUCCESS) { - result = 1; - unset(*scope, "ddns-fwd-name"); - unset(*scope, "ddns-txt"); - try_rev: - if (find_bound_string(&ddns_rev_name, *scope, - "ddns-rev-name")) { - if (ddns_remove_ptr(&ddns_rev_name) == NOERROR) { - unset(*scope, "ddns-rev-name"); - if (client_updated) - unset(*scope, "ddns-client-fqdn"); - /* XXX this is to compensate for a bug in - XXX 3.0rc8, and should be removed before - XXX 3.0pl1. */ - else if (!ddns_fwd_name.len) - unset(*scope, "ddns-text"); - } else - result = 0; + /* Check if client did update */ + if (find_bound_string(&ddns_cb->fwd_name, *scope, + "ddns-client-fqdn")) { + ddns_cb->flags |= DDNS_CLIENT_DID_UPDATE; } } - data_string_forget (&ddns_fwd_name, MDL); - data_string_forget (&ddns_rev_name, MDL); - data_string_forget (&ddns_dhcid, MDL); + /* + * Find the ptr name and copy it to the control block. If we don't + * have it this isn't an interim or rfc3??? record so we can't delete + * the A record using this mechanism but we can delete the ptr record. + * In this case we will attempt to do any requested next step. + */ + memset(&leaseid, 0, sizeof(leaseid)); + if (!find_bound_string (&leaseid, *scope, "ddns-txt")) { + ddns_cb->flags &= ~DDNS_UPDATE_ADDR; + } else { + if (dhcid_fromlease(&ddns_cb->dhcid, &leaseid) != + ISC_R_SUCCESS) { + /* We couldn't convert the dhcid from the lease + * version to the dns version. We can't delete + * the A record but can continue to the ptr + */ + ddns_cb->flags &= ~DDNS_UPDATE_ADDR; + } + data_string_forget(&leaseid, MDL); + } - return result; + /* + * Find the rev name and copy it to the control block. If we don't + * have it we can't get rid of it but we can try to remove the fwd + * pointer if desired. + */ + if (!find_bound_string(&ddns_cb->rev_name, *scope, "ddns-rev-name")) { + ddns_cb->flags &= ~DDNS_UPDATE_PTR; + } + + /* + * If we have a second control block for doing an add + * after the remove finished attach it to our control block. + */ + ddns_cb->next_op = add_ddns_cb; + + /* + * Now that we've collected the information we can try to process it. + * If necessary we call an appropriate routine to send a message and + * provide it with an action routine to run on the control block given + * the results of the message. We have three entry points from here, + * one for removing the A record, the next for removing the PTR and + * the third for doing any requested add. + */ + if ((ddns_cb->flags & DDNS_UPDATE_ADDR) != 0) { + if (ddns_cb->fwd_name.len != 0) { + ddns_cb->state = DDNS_STATE_REM_FW_YXDHCID; + ddns_cb->cur_func = ddns_fwd_srv_rem1; + + rcode = ddns_modify_fwd(ddns_cb); + if (rcode == ISC_R_SUCCESS) { + ddns_update_lease_ptr(lease, lease6, ddns_cb, + ddns_cb); + return(1); + } + + /* + * We weren't able to process the request tag the + * add so we won't execute it. + */ + execute_add = ISC_R_FAILURE; + goto cleanup; + } + else { + /*remove info from scope */ + unset(*scope, "ddns-fwd-name"); + unset(*scope, "ddns-txt"); + } + } + + if ((ddns_cb->flags & DDNS_UPDATE_PTR) != 0) { + ddns_cb->state = DDNS_STATE_REM_PTR; + ddns_cb->cur_func = ddns_ptr_remove; + + /* + * if execute add isn't success remove the control block so + * it won't be processed when the remove completes. We + * also arrange to clean it up and get rid of it. + */ + if (execute_add != ISC_R_SUCCESS) { + ddns_cb->next_op = NULL; + ddns_fwd_srv_connector(lease, lease6, scope, + add_ddns_cb, execute_add); + add_ddns_cb = NULL; + } + else { + result = 1; + } + + rcode = ddns_modify_ptr(ddns_cb); + if (rcode == ISC_R_SUCCESS) { + ddns_update_lease_ptr(lease, lease6, ddns_cb, ddns_cb); + return(result); + } + + /* We weren't able to process the request tag the + * add so we won't execute it */ + execute_add = ISC_R_FAILURE; + goto cleanup; + } + + cleanup: + /* + * We've gotten here because we didn't need to send a message or + * we failed when trying to do so. We send the additional cb + * off to handle sending and/or cleanup and cleanup anything + * we allocated here. + */ + ddns_fwd_srv_connector(lease, lease6, scope, add_ddns_cb, execute_add); + ddns_cb_free(ddns_cb, MDL); + + return(result); } #endif /* NSUPDATE */ diff --git a/server/dhcpd.c b/server/dhcpd.c index e1cbe67f..0bd8e1e7 100644 --- a/server/dhcpd.c +++ b/server/dhcpd.c @@ -155,8 +155,8 @@ on commit { \n\ } \n\ }"; -int ddns_update_style; #endif /* NSUPDATE */ +int ddns_update_style; const char *path_dhcpd_conf = _PATH_DHCPD_CONF; const char *path_dhcpd_db = _PATH_DHCPD_DB; @@ -177,7 +177,7 @@ static isc_result_t verify_addr (omapi_object_t *l, omapi_addr_t *addr) { static isc_result_t verify_auth (omapi_object_t *p, omapi_auth_key_t *a) { if (a != omapi_key) - return ISC_R_INVALIDKEY; + return DHCP_R_INVALIDKEY; return ISC_R_SUCCESS; } @@ -242,8 +242,10 @@ main(int argc, char **argv) { isc_result_t result; unsigned seed; struct interface_info *ip; +#if defined (NSUPDATE) struct parse *parse; int lose; +#endif int no_dhcpd_conf = 0; int no_dhcpd_db = 0; int no_dhcpd_pid = 0; @@ -277,6 +279,12 @@ main(int argc, char **argv) { else if (fd != -1) close(fd); + /* Set up the isc and dns library managers */ + status = dhcp_context_create(); + if (status != ISC_R_SUCCESS) + log_fatal("Can't initialize context: %s", + isc_result_totext(status)); + /* Set up the client classification system. */ classification_setup (); @@ -844,7 +852,9 @@ void postconf_initialization (int quiet) struct option_cache *oc; char *s; isc_result_t result; +#if defined (NSUPDATE) struct parse *parse; +#endif int tmp; /* Now try to get the lease file name. */ @@ -1033,6 +1043,17 @@ void postconf_initialization (int quiet) } else { ddns_update_style = DDNS_UPDATE_STYLE_NONE; } +#if defined (NSUPDATE) + /* We no longer support ad_hoc, tell the user */ + if (ddns_update_style == DDNS_UPDATE_STYLE_AD_HOC) { + log_fatal("ddns-update-style ad_hoc no longer supported"); + } +#else + /* If we don't have support for updates compiled in tell the user */ + if (ddns_update_style != DDNS_UPDATE_STYLE_NONE) { + log_fatal("Support for ddns-update-style not compiled in"); + } +#endif oc = lookup_option (&server_universe, options, SV_LOG_FACILITY); if (oc) { @@ -1456,5 +1477,5 @@ isc_result_t dhcp_set_control_state (control_object_state_t oldstate, dhcp_io_shutdown_countdown (0); return ISC_R_SUCCESS; } - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } diff --git a/server/dhcpleasequery.c b/server/dhcpleasequery.c index 8a142f7b..b1d8dce6 100644 --- a/server/dhcpleasequery.c +++ b/server/dhcpleasequery.c @@ -718,7 +718,7 @@ get_lq_query(struct lq6_state *lq) * Verify our lq_query structure is empty. */ if ((lq_query->data != NULL) || (lq_query->len != 0)) { - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } oc = lookup_option(&dhcpv6_universe, packet->options, D6O_LQ_QUERY); diff --git a/server/dhcpv6.c b/server/dhcpv6.c index 7c029b0e..4ced893c 100644 --- a/server/dhcpv6.c +++ b/server/dhcpv6.c @@ -288,7 +288,7 @@ generate_new_server_duid(void) { if ((server_duid_type != DUID_LL) && (server_duid_type != DUID_LLT)) { log_error("Invalid DUID type %d specified, " "only LL and LLT types supported", server_duid_type); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } /* @@ -355,7 +355,7 @@ get_client_id(struct packet *packet, struct data_string *client_id) { * Verify our client_id structure is empty. */ if ((client_id->data != NULL) || (client_id->len != 0)) { - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } oc = lookup_option(&dhcpv6_universe, packet->options, D6O_CLIENTID); @@ -949,7 +949,7 @@ try_client_v6_address(struct iasubopt **addr, isc_result_t result; if (requested_addr->len < sizeof(tmp_addr)) { - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } memcpy(&tmp_addr, requested_addr->data, sizeof(tmp_addr)); if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr)) { @@ -1088,7 +1088,7 @@ try_client_v6_prefix(struct iasubopt **pref, isc_result_t result; if (requested_pref->len < sizeof(tmp_plen) + sizeof(tmp_pref)) { - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } tmp_plen = (int) requested_pref->data[0]; if ((tmp_plen < 3) || (tmp_plen > 128)) { @@ -1599,7 +1599,7 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) { if (reply->fixed.len < 16) { log_error("reply_process_ia_na: invalid fixed address."); - status = ISC_R_INVALIDARG; + status = DHCP_R_INVALIDARG; goto cleanup; } @@ -1838,6 +1838,7 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) { renew_lease6(tmp->ipv6_pool, tmp); schedule_lease_timeout(tmp->ipv6_pool); +#if defined (NSUPDATE) /* * Perform ddns updates. */ @@ -1853,6 +1854,7 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) { ddns_updates(reply->packet, NULL, NULL, tmp, NULL, reply->opt_state); } +#endif } /* Remove any old ia from the hash. */ @@ -2494,6 +2496,7 @@ reply_process_ia_ta(struct reply_state *reply, struct option_cache *ia) { renew_lease6(tmp->ipv6_pool, tmp); schedule_lease_timeout(tmp->ipv6_pool); +#if defined (NSUPDATE) /* * Perform ddns updates. */ @@ -2509,6 +2512,7 @@ reply_process_ia_ta(struct reply_state *reply, struct option_cache *ia) { ddns_updates(reply->packet, NULL, NULL, tmp, NULL, reply->opt_state); } +#endif } /* Remove any old ia from the hash. */ @@ -2700,7 +2704,7 @@ reply_process_try_addr(struct reply_state *reply, struct iaddr *addr) { if ((reply == NULL) || (reply->shared == NULL) || (reply->shared->ipv6_pools == NULL) || (addr == NULL) || (reply->lease != NULL)) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; memset(&data_addr, 0, sizeof(data_addr)); data_addr.len = addr->len; @@ -2736,7 +2740,7 @@ find_client_address(struct reply_state *reply) { if (reply->static_lease) { if (reply->host == NULL) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; send_addr.len = 16; memcpy(send_addr.iabuf, reply->fixed.data, 16); @@ -3671,7 +3675,7 @@ reply_process_try_prefix(struct reply_state *reply, if ((reply == NULL) || (reply->shared == NULL) || (reply->shared->ipv6_pools == NULL) || (pref == NULL) || (reply->lease != NULL)) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; memset(&data_pref, 0, sizeof(data_pref)); data_pref.len = 17; @@ -3713,7 +3717,7 @@ find_client_prefix(struct reply_state *reply) { struct iaddrcidrnetlist *l; if (reply->host == NULL) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; for (l = reply->host->fixed_prefix; l != NULL; l = l->next) { if (l->cidrnet.bits == reply->preflen) @@ -4135,7 +4139,7 @@ shared_network_from_packet6(struct shared_network **shared, isc_result_t status; if ((shared == NULL) || (*shared != NULL) || (packet == NULL)) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* * First, find the link address where the packet from the client diff --git a/server/failover.c b/server/failover.c index 5c84922b..44c8f750 100644 --- a/server/failover.c +++ b/server/failover.c @@ -76,7 +76,7 @@ void dhcp_failover_startup () /* In case the peer is already running, immediately try to establish a connection with it. */ status = dhcp_failover_link_initiate ((omapi_object_t *)state); - if (status != ISC_R_SUCCESS && status != ISC_R_INCOMPLETE) { + if (status != ISC_R_SUCCESS && status != DHCP_R_INCOMPLETE) { #if defined (DEBUG_FAILOVER_TIMING) log_info ("add_timeout +90 dhcp_failover_reconnect"); #endif @@ -195,7 +195,7 @@ isc_result_t dhcp_failover_link_initiate (omapi_object_t *h) break; } if (!o) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; state = (dhcp_failover_state_t *)o; obj = (dhcp_failover_link_t *)0; @@ -258,7 +258,7 @@ isc_result_t dhcp_failover_link_initiate (omapi_object_t *h) data_string_forget (&ds, MDL); dhcp_failover_link_dereference (&obj, MDL); omapi_addr_list_dereference (&addrs, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } local_addr.addrtype = AF_INET; local_addr.addrlen = ds.len; @@ -387,7 +387,7 @@ isc_result_t dhcp_failover_link_signal (omapi_object_t *h, } if (!h -> outer || h -> outer -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; c = h -> outer; /* We get here because we requested that we be woken up after @@ -589,7 +589,7 @@ isc_result_t dhcp_failover_link_signal (omapi_object_t *h, log_info ("failover: connect: no matching state."); omapi_disconnect (c, 1); link -> state = dhcp_flink_disconnected; - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } /* Once we have the entire message, and we've validated @@ -628,7 +628,7 @@ static isc_result_t do_a_failover_option (c, link) if (link -> imsg_count + 2 > link -> imsg_len) { log_error ("FAILOVER: message overflow at option code."); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } /* Get option code. */ @@ -637,7 +637,7 @@ static isc_result_t do_a_failover_option (c, link) if (link -> imsg_count + 2 > link -> imsg_len) { log_error ("FAILOVER: message overflow at length."); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } /* Get option length. */ @@ -646,7 +646,7 @@ static isc_result_t do_a_failover_option (c, link) if (link -> imsg_count + option_len > link -> imsg_len) { log_error ("FAILOVER: message overflow at data."); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } /* If it's an unknown code, skip over it. */ @@ -668,7 +668,7 @@ static isc_result_t do_a_failover_option (c, link) link -> imsg_count += option_len; if (link -> imsg_count != link -> imsg_len) { log_error ("FAILOVER: digest not at end of message"); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } #if defined (DEBUG_FAILOVER_MESSAGES) log_debug (" option %s len %d", @@ -683,7 +683,7 @@ static isc_result_t do_a_failover_option (c, link) if (link -> imsg -> options_present & ft_options [option_code].bit) { log_error ("FAILOVER: duplicate option %s", ft_options [option_code].name); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } /* Make sure the option is appropriate for this type of message. @@ -718,7 +718,7 @@ static isc_result_t do_a_failover_option (c, link) (ft_sizes [ft_options [option_code].type] * ft_options [option_code].num_present), ft_options [option_code].name); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } } else { failover_option_t *fo; @@ -751,7 +751,7 @@ static isc_result_t do_a_failover_option (c, link) /* Actually, NO_MEMORY, but if we lose here we have to drop the connection. */ - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } omapi_connection_copyout (ddns -> data, c, op_count); goto out; @@ -769,7 +769,7 @@ static isc_result_t do_a_failover_option (c, link) if (op_size > 1 && option_len % op_size) { log_error ("FAILOVER: option_len %d not %s%d", option_len, "multiple of ", op_size); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } op_count = option_len / op_size; @@ -784,7 +784,7 @@ static isc_result_t do_a_failover_option (c, link) log_error ("FAILOVER: no memory getting %s (%d)", "option data", op_count); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } op = fo -> data; } @@ -848,7 +848,7 @@ static isc_result_t do_a_failover_option (c, link) log_error ("FAILOVER: option %s: bad type %d", ft_options [option_code].name, ft_options [option_code].type); - return ISC_R_PROTOCOLERROR; + return DHCP_R_PROTOCOLERROR; } } out: @@ -863,7 +863,7 @@ isc_result_t dhcp_failover_link_set_value (omapi_object_t *h, omapi_typed_data_t *value) { if (h -> type != omapi_type_protocol) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* Never valid to set these. */ if (!omapi_ds_strcmp (name, "link-port") || @@ -885,7 +885,7 @@ isc_result_t dhcp_failover_link_get_value (omapi_object_t *h, dhcp_failover_link_t *link; if (h -> type != omapi_type_protocol) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; link = (dhcp_failover_link_t *)h; if (!omapi_ds_strcmp (name, "link-port")) { @@ -913,7 +913,7 @@ isc_result_t dhcp_failover_link_destroy (omapi_object_t *h, { dhcp_failover_link_t *link; if (h -> type != dhcp_type_failover_link) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; link = (dhcp_failover_link_t *)h; if (link -> peer_address) @@ -937,7 +937,7 @@ isc_result_t dhcp_failover_link_stuff_values (omapi_object_t *c, isc_result_t status; if (l -> type != dhcp_type_failover_link) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; link = (dhcp_failover_link_t *)l; status = omapi_connection_put_name (c, "link-port"); @@ -985,7 +985,7 @@ isc_result_t dhcp_failover_listen (omapi_object_t *h) return status; if (!value -> value) { omapi_value_dereference (&value, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } status = omapi_get_int_value (&port, value -> value); @@ -1001,7 +1001,7 @@ isc_result_t dhcp_failover_listen (omapi_object_t *h) if (!value -> value) { nogood: omapi_value_dereference (&value, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (value -> value -> type != omapi_datatype_data || @@ -1074,7 +1074,7 @@ isc_result_t dhcp_failover_listener_signal (omapi_object_t *o, dhcp_failover_state_t *s, *state = (dhcp_failover_state_t *)0; if (!o || o -> type != dhcp_type_failover_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; p = (dhcp_failover_listener_t *)o; /* Not a signal we recognize? */ @@ -1087,7 +1087,7 @@ isc_result_t dhcp_failover_listener_signal (omapi_object_t *o, c = va_arg (ap, omapi_connection_object_t *); if (!c || c -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* See if we can find a failover_state object that matches this connection. */ @@ -1141,7 +1141,7 @@ isc_result_t dhcp_failover_listener_set_value (omapi_object_t *h, omapi_typed_data_t *value) { if (h -> type != dhcp_type_failover_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (h -> inner && h -> inner -> type -> set_value) return (*(h -> inner -> type -> set_value)) @@ -1155,7 +1155,7 @@ isc_result_t dhcp_failover_listener_get_value (omapi_object_t *h, omapi_value_t **value) { if (h -> type != dhcp_type_failover_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (h -> inner && h -> inner -> type -> get_value) return (*(h -> inner -> type -> get_value)) @@ -1169,7 +1169,7 @@ isc_result_t dhcp_failover_listener_destroy (omapi_object_t *h, dhcp_failover_listener_t *l; if (h -> type != dhcp_type_failover_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; l = (dhcp_failover_listener_t *)h; if (l -> next) dhcp_failover_listener_dereference (&l -> next, file, line); @@ -1185,7 +1185,7 @@ isc_result_t dhcp_failover_listener_stuff (omapi_object_t *c, omapi_object_t *p) { if (p -> type != dhcp_type_failover_listener) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (p -> inner && p -> inner -> type -> stuff_values) return (*(p -> inner -> type -> stuff_values)) (c, id, @@ -1208,7 +1208,7 @@ isc_result_t dhcp_failover_register (omapi_object_t *h) return status; if (!value -> value) { omapi_value_dereference (&value, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } status = omapi_get_int_value (&port, value -> value); @@ -1248,7 +1248,7 @@ isc_result_t dhcp_failover_state_signal (omapi_object_t *o, struct timeval tv; if (!o || o -> type != dhcp_type_failover_state) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; state = (dhcp_failover_state_t *)o; /* Not a signal we recognize? */ @@ -1606,7 +1606,7 @@ isc_result_t dhcp_failover_state_transition (dhcp_failover_state_t *state, break; } } - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } isc_result_t dhcp_failover_set_service_state (dhcp_failover_state_t *state) @@ -2953,7 +2953,7 @@ isc_result_t dhcp_failover_state_set_value (omapi_object_t *h, isc_result_t status; if (h -> type != dhcp_type_failover_state) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* This list of successful returns is completely wrong, but the fastest way to make dhcpctl do something vaguely sane when @@ -3028,7 +3028,7 @@ void dhcp_failover_reconnect (void *vs) return; status = dhcp_failover_link_initiate ((omapi_object_t *)state); - if (status != ISC_R_SUCCESS && status != ISC_R_INCOMPLETE) { + if (status != ISC_R_SUCCESS && status != DHCP_R_INCOMPLETE) { log_info ("failover peer %s: %s", state -> name, isc_result_totext (status)); #if defined (DEBUG_FAILOVER_TIMING) @@ -3119,7 +3119,7 @@ isc_result_t dhcp_failover_state_get_value (omapi_object_t *h, isc_result_t status; if (h -> type != dhcp_type_failover_state) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; s = (dhcp_failover_state_t *)h; if (!omapi_ds_strcmp (name, "name")) { @@ -3213,7 +3213,7 @@ isc_result_t dhcp_failover_state_destroy (omapi_object_t *h, dhcp_failover_state_t *s; if (h -> type != dhcp_type_failover_state) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; s = (dhcp_failover_state_t *)h; if (s -> link_to_peer) @@ -3261,11 +3261,11 @@ isc_result_t dhcp_failover_state_stuff (omapi_object_t *c, isc_result_t status; if (c -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; conn = (omapi_connection_object_t *)c; if (h -> type != dhcp_type_failover_state) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; s = (dhcp_failover_state_t *)h; status = omapi_connection_put_name (c, "name"); @@ -3482,7 +3482,7 @@ isc_result_t dhcp_failover_state_lookup (omapi_object_t **sp, dhcp_failover_state_t *s; if (!ref) - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; /* First see if we were sent a handle. */ status = omapi_get_value_str (ref, id, "handle", &tv); @@ -3496,7 +3496,7 @@ isc_result_t dhcp_failover_state_lookup (omapi_object_t **sp, /* Don't return the object if the type is wrong. */ if ((*sp) -> type != dhcp_type_failover_state) { omapi_object_dereference (sp, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } } @@ -3516,7 +3516,7 @@ isc_result_t dhcp_failover_state_lookup (omapi_object_t **sp, then the query was invalid. */ if (*sp && *sp != (omapi_object_t *)s) { omapi_object_dereference (sp, MDL); - return ISC_R_KEYCONFLICT; + return DHCP_R_KEYCONFLICT; } else if (!s) { if (*sp) omapi_object_dereference (sp, MDL); @@ -3530,7 +3530,7 @@ isc_result_t dhcp_failover_state_lookup (omapi_object_t **sp, /* If we get to here without finding a lease, no valid key was specified. */ if (!*sp) - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; return ISC_R_SUCCESS; } @@ -4177,7 +4177,7 @@ isc_result_t dhcp_failover_put_message (dhcp_failover_link_t *link, va_end(list); if (bad_option) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* Now send the message header. */ @@ -4325,12 +4325,12 @@ isc_result_t dhcp_failover_send_state (dhcp_failover_state_t *state) #endif if (!state || state -> type != dhcp_type_failover_state) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; link = state -> link_to_peer; if (!link || !link -> outer || link -> outer -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; status = (dhcp_failover_put_message (link, link -> outer, @@ -4375,11 +4375,11 @@ isc_result_t dhcp_failover_send_connect (omapi_object_t *l) #endif if (!l || l -> type != dhcp_type_failover_link) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; link = (dhcp_failover_link_t *)l; state = link -> state_object; if (!l -> outer || l -> outer -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; status = (dhcp_failover_put_message @@ -4432,10 +4432,10 @@ isc_result_t dhcp_failover_send_connectack (omapi_object_t *l, #endif if (!l || l -> type != dhcp_type_failover_link) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; link = (dhcp_failover_link_t *)l; if (!l -> outer || l -> outer -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; status = (dhcp_failover_put_message @@ -4502,11 +4502,11 @@ isc_result_t dhcp_failover_send_disconnect (omapi_object_t *l, #endif if (!l || l -> type != dhcp_type_failover_link) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; link = (dhcp_failover_link_t *)l; state = link -> state_object; if (!l -> outer || l -> outer -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (!message && reason) message = dhcp_failover_reject_reason_print (reason); @@ -4554,11 +4554,11 @@ isc_result_t dhcp_failover_send_bind_update (dhcp_failover_state_t *state, if (!state -> link_to_peer || state -> link_to_peer -> type != dhcp_type_failover_link) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; link = (dhcp_failover_link_t *)state -> link_to_peer; if (!link -> outer || link -> outer -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; transmit_state = lease->desired_binding_state; if (lease->flags & RESERVED_LEASE) { @@ -4651,11 +4651,11 @@ isc_result_t dhcp_failover_send_bind_ack (dhcp_failover_state_t *state, if (!state -> link_to_peer || state -> link_to_peer -> type != dhcp_type_failover_link) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; link = (dhcp_failover_link_t *)state -> link_to_peer; if (!link -> outer || link -> outer -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (!message && reason) message = dhcp_failover_reject_reason_print (reason); @@ -4735,11 +4735,11 @@ isc_result_t dhcp_failover_send_poolreq (dhcp_failover_state_t *state) if (!state -> link_to_peer || state -> link_to_peer -> type != dhcp_type_failover_link) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; link = (dhcp_failover_link_t *)state -> link_to_peer; if (!link -> outer || link -> outer -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; status = (dhcp_failover_put_message (link, link -> outer, @@ -4774,11 +4774,11 @@ isc_result_t dhcp_failover_send_poolresp (dhcp_failover_state_t *state, if (!state -> link_to_peer || state -> link_to_peer -> type != dhcp_type_failover_link) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; link = (dhcp_failover_link_t *)state -> link_to_peer; if (!link -> outer || link -> outer -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; status = (dhcp_failover_put_message (link, link -> outer, @@ -4814,11 +4814,11 @@ isc_result_t dhcp_failover_send_update_request (dhcp_failover_state_t *state) if (!state -> link_to_peer || state -> link_to_peer -> type != dhcp_type_failover_link) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; link = (dhcp_failover_link_t *)state -> link_to_peer; if (!link -> outer || link -> outer -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (state -> curUPD) return ISC_R_ALREADYRUNNING; @@ -4860,11 +4860,11 @@ isc_result_t dhcp_failover_send_update_request_all (dhcp_failover_state_t if (!state -> link_to_peer || state -> link_to_peer -> type != dhcp_type_failover_link) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; link = (dhcp_failover_link_t *)state -> link_to_peer; if (!link -> outer || link -> outer -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* If there is an UPDREQ in progress, then upgrade to UPDREQALL. */ if (state -> curUPD && (state -> curUPD != FTM_UPDREQ)) @@ -4906,11 +4906,11 @@ isc_result_t dhcp_failover_send_update_done (dhcp_failover_state_t *state) if (!state -> link_to_peer || state -> link_to_peer -> type != dhcp_type_failover_link) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; link = (dhcp_failover_link_t *)state -> link_to_peer; if (!link -> outer || link -> outer -> type != omapi_type_connection) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; status = (dhcp_failover_put_message (link, link -> outer, @@ -5187,7 +5187,7 @@ isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *state, */ if (msg->binding_status == FTS_ACTIVE && (chaddr_changed || ident_changed)) { - ddns_removals(lease, NULL); + ddns_removals(lease, NULL, NULL); if (lease->scope != NULL) binding_scope_dereference(&lease->scope, MDL); diff --git a/server/mdb.c b/server/mdb.c index c23c0e23..5d371fb1 100644 --- a/server/mdb.c +++ b/server/mdb.c @@ -75,7 +75,7 @@ isc_result_t enter_class(cd, dynamicp, commit) if (!collections -> classes) { /* A subclass with no parent is invalid. */ if (cd->name == NULL) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; class_reference (&collections -> classes, cd, MDL); } else if (cd->name != NULL) { /* regular class */ @@ -1219,6 +1219,9 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate) comp->ends = lease->ends; comp->next_binding_state = lease->next_binding_state; + /* move the ddns control block information */ + comp->ddns_cb = lease->ddns_cb; + just_move_it: #if defined (FAILOVER_PROTOCOL) /* Atsfp should be cleared upon any state change that implies @@ -1411,7 +1414,7 @@ void make_binding_state_transition (struct lease *lease) lease -> binding_state == FTS_ACTIVE && lease -> next_binding_state != FTS_RELEASED))) { #if defined (NSUPDATE) - ddns_removals(lease, NULL); + ddns_removals(lease, NULL, NULL); #endif if (lease -> on_expiry) { execute_statements ((struct binding_value **)0, @@ -1477,7 +1480,7 @@ void make_binding_state_transition (struct lease *lease) * release message. This is not true of expiry, where the * peer may have extended the lease. */ - ddns_removals(lease, NULL); + ddns_removals(lease, NULL, NULL); #endif if (lease -> on_release) { execute_statements ((struct binding_value **)0, @@ -1646,7 +1649,7 @@ void release_lease (lease, packet) /* If there are statements to execute when the lease is released, execute them. */ #if defined (NSUPDATE) - ddns_removals(lease, NULL); + ddns_removals(lease, NULL, NULL); #endif if (lease -> on_release) { execute_statements ((struct binding_value **)0, @@ -1707,7 +1710,7 @@ void abandon_lease (lease, message) { struct lease *lt = (struct lease *)0; #if defined (NSUPDATE) - ddns_removals(lease, NULL); + ddns_removals(lease, NULL, NULL); #endif if (!lease_copy (<, lease, MDL)) @@ -1739,7 +1742,7 @@ void dissociate_lease (lease) { struct lease *lt = (struct lease *)0; #if defined (NSUPDATE) - ddns_removals(lease, NULL); + ddns_removals(lease, NULL, NULL); #endif if (!lease_copy (<, lease, MDL)) diff --git a/server/mdb6.c b/server/mdb6.c index 73b7fdfa..ff717299 100644 --- a/server/mdb6.c +++ b/server/mdb6.c @@ -21,13 +21,11 @@ #include #include -#include "isc-dhcp/result.h" - #include #include "dhcpd.h" #include "omapip/omapip.h" #include "omapip/hash.h" -#include "dst/md5.h" +#include HASH_FUNCTIONS(ia, unsigned char *, struct ia_xx, ia_hash_t, ia_reference, ia_dereference, do_string_hash); @@ -54,11 +52,11 @@ iasubopt_allocate(struct iasubopt **iasubopt, const char *file, int line) { if (iasubopt == NULL) { log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (*iasubopt != NULL) { log_error("%s(%d): non-NULL pointer", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } tmp = dmalloc(sizeof(*tmp), file, line); @@ -86,15 +84,15 @@ iasubopt_reference(struct iasubopt **iasubopt, struct iasubopt *src, const char *file, int line) { if (iasubopt == NULL) { log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (*iasubopt != NULL) { log_error("%s(%d): non-NULL pointer", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (src == NULL) { log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } *iasubopt = src; src->refcnt++; @@ -114,7 +112,7 @@ iasubopt_dereference(struct iasubopt **iasubopt, const char *file, int line) { if ((iasubopt == NULL) || (*iasubopt == NULL)) { log_error("%s(%d): NULL pointer", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } tmp = *iasubopt; @@ -180,11 +178,11 @@ ia_allocate(struct ia_xx **ia, u_int32_t iaid, if (ia == NULL) { log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (*ia != NULL) { log_error("%s(%d): non-NULL pointer", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } tmp = dmalloc(sizeof(*tmp), file, line); @@ -215,15 +213,15 @@ ia_reference(struct ia_xx **ia, struct ia_xx *src, const char *file, int line) { if (ia == NULL) { log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (*ia != NULL) { log_error("%s(%d): non-NULL pointer", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (src == NULL) { log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } *ia = src; src->refcnt++; @@ -243,7 +241,7 @@ ia_dereference(struct ia_xx **ia, const char *file, int line) { if ((ia == NULL) || (*ia == NULL)) { log_error("%s(%d): NULL pointer", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } tmp = *ia; @@ -459,11 +457,11 @@ ipv6_pool_allocate(struct ipv6_pool **pool, u_int16_t type, if (pool == NULL) { log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (*pool != NULL) { log_error("%s(%d): non-NULL pointer", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } tmp = dmalloc(sizeof(*tmp), file, line); @@ -480,13 +478,13 @@ ipv6_pool_allocate(struct ipv6_pool **pool, u_int16_t type, dfree(tmp, file, line); return ISC_R_NOMEMORY; } - if (isc_heap_create(lease_older, lease_index_changed, + if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, lease_index_changed, 0, &(tmp->active_timeouts)) != ISC_R_SUCCESS) { iasubopt_free_hash_table(&(tmp->leases), file, line); dfree(tmp, file, line); return ISC_R_NOMEMORY; } - if (isc_heap_create(lease_older, lease_index_changed, + if (isc_heap_create(dhcp_gbl_ctx.mctx, lease_older, lease_index_changed, 0, &(tmp->inactive_timeouts)) != ISC_R_SUCCESS) { isc_heap_destroy(&(tmp->active_timeouts)); iasubopt_free_hash_table(&(tmp->leases), file, line); @@ -509,15 +507,15 @@ ipv6_pool_reference(struct ipv6_pool **pool, struct ipv6_pool *src, const char *file, int line) { if (pool == NULL) { log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (*pool != NULL) { log_error("%s(%d): non-NULL pointer", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (src == NULL) { log_error("%s(%d): NULL pointer reference", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } *pool = src; src->refcnt++; @@ -569,7 +567,7 @@ ipv6_pool_dereference(struct ipv6_pool **pool, const char *file, int line) { if ((pool == NULL) || (*pool == NULL)) { log_error("%s(%d): NULL pointer", file, line); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } tmp = *pool; @@ -603,7 +601,7 @@ static void build_address6(struct in6_addr *addr, const struct in6_addr *net_start_addr, int net_bits, const struct data_string *input) { - MD5_CTX ctx; + isc_md5_t ctx; int net_bytes; int i; char *str; @@ -614,9 +612,9 @@ build_address6(struct in6_addr *addr, * Yes, we know MD5 isn't cryptographically sound. * No, we don't care. */ - MD5_Init(&ctx); - MD5_Update(&ctx, input->data, input->len); - MD5_Final((unsigned char *)addr, &ctx); + isc_md5_init(&ctx); + isc_md5_update(&ctx, input->data, input->len); + isc_md5_final(&ctx, (unsigned char *)addr); /* * Copy the [0..128] network bits over. @@ -654,28 +652,27 @@ static void build_temporary6(struct in6_addr *addr, const struct in6_addr *net_start_addr, int net_bits, const struct data_string *input) { - static u_int8_t history[8]; + static u_int32_t history[2]; static u_int32_t counter = 0; - MD5_CTX ctx; + isc_md5_t ctx; unsigned char md[16]; - extern int dst_s_random(u_int8_t *, unsigned); /* * First time/time to reseed. * Please use a good pseudo-random generator here! */ if (counter == 0) { - if (dst_s_random(history, 8) != 8) - log_fatal("Random failed."); + isc_random_get(&history[0]); + isc_random_get(&history[1]); } /* * Use MD5 as recommended by RFC 4941. */ - MD5_Init(&ctx); - MD5_Update(&ctx, history, 8UL); - MD5_Update(&ctx, input->data, input->len); - MD5_Final(md, &ctx); + isc_md5_init(&ctx); + isc_md5_update(&ctx, (unsigned char *)&history[0], 8UL); + isc_md5_update(&ctx, input->data, input->len); + isc_md5_final(&ctx, md); /* * Build the address. @@ -715,7 +712,7 @@ build_temporary6(struct in6_addr *addr, /* * Save history for the next call. */ - memcpy(history, md + 8, 8); + memcpy((unsigned char *)&history[0], md + 8, 8); counter++; } @@ -802,10 +799,10 @@ create_lease6(struct ipv6_pool *pool, struct iasubopt **addr, case D6O_IA_PD: /* prefix */ log_error("create_lease6: prefix pool."); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; default: log_error("create_lease6: untyped pool."); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } /* @@ -1044,10 +1041,12 @@ move_lease_to_inactive(struct ipv6_pool *pool, struct iasubopt *lease, old_heap_index = lease->heap_index; insert_result = isc_heap_insert(pool->inactive_timeouts, lease); if (insert_result == ISC_R_SUCCESS) { +#if defined (NSUPDATE) /* Process events upon expiration. */ if (pool->pool_type != D6O_IA_PD) { - ddns_removals(NULL, lease); + ddns_removals(NULL, lease, NULL); } +#endif /* Binding scopes are no longer valid after expiry or * release. @@ -1083,11 +1082,11 @@ expire_lease6(struct iasubopt **leasep, struct ipv6_pool *pool, time_t now) { if (leasep == NULL) { log_error("%s(%d): NULL pointer reference", MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (*leasep != NULL) { log_error("%s(%d): non-NULL pointer", MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (pool->num_active > 0) { @@ -1147,7 +1146,7 @@ build_prefix6(struct in6_addr *pref, const struct in6_addr *net_start_pref, int pool_bits, int pref_bits, const struct data_string *input) { - MD5_CTX ctx; + isc_md5_t ctx; int net_bytes; int i; char *str; @@ -1158,9 +1157,9 @@ build_prefix6(struct in6_addr *pref, * Yes, we know MD5 isn't cryptographically sound. * No, we don't care. */ - MD5_Init(&ctx); - MD5_Update(&ctx, input->data, input->len); - MD5_Final((unsigned char *)pref, &ctx); + isc_md5_init(&ctx); + isc_md5_update(&ctx, input->data, input->len); + isc_md5_final(&ctx, (unsigned char *)pref); /* * Copy the network bits over. @@ -1467,9 +1466,11 @@ lease_timeout_support(void *vpool) { * DH: Do we want to do this on a special 'depref' * timer rather than expiration timer? */ +#if defined (NSUPDATE) if (pool->pool_type != D6O_IA_PD) { - ddns_removals(NULL, lease); + ddns_removals(NULL, lease, NULL); } +#endif write_ia(lease->ia); @@ -1624,11 +1625,11 @@ find_ipv6_pool(struct ipv6_pool **pool, u_int16_t type, if (pool == NULL) { log_error("%s(%d): NULL pointer reference", MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (*pool != NULL) { log_error("%s(%d): non-NULL pointer", MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } for (i=0; i type != dhcp_type_lease) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; lease = (struct lease *)h; /* We're skipping a lot of things it might be interesting to @@ -222,7 +222,7 @@ isc_result_t dhcp_lease_set_value (omapi_object_t *h, return status; if (bar < 1 || bar > FTS_LAST) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; nls = binding_state_names [bar - 1]; if (lease -> binding_state >= 1 && lease -> binding_state <= FTS_LAST) @@ -241,19 +241,19 @@ isc_result_t dhcp_lease_set_value (omapi_object_t *h, piaddr (lease -> ip_addr), ols, nls); return ISC_R_IOERROR; } - return ISC_R_UNCHANGED; + return DHCP_R_UNCHANGED; } else if (!omapi_ds_strcmp (name, "ip-address")) { return ISC_R_NOPERM; } else if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) { - return ISC_R_UNCHANGED; /* XXX take change. */ + return DHCP_R_UNCHANGED; /* XXX take change. */ } else if (!omapi_ds_strcmp (name, "hostname")) { - return ISC_R_UNCHANGED; /* XXX take change. */ + return DHCP_R_UNCHANGED; /* XXX take change. */ } else if (!omapi_ds_strcmp (name, "client-hostname")) { - return ISC_R_UNCHANGED; /* XXX take change. */ + return DHCP_R_UNCHANGED; /* XXX take change. */ } else if (!omapi_ds_strcmp (name, "host")) { - return ISC_R_UNCHANGED; /* XXX take change. */ + return DHCP_R_UNCHANGED; /* XXX take change. */ } else if (!omapi_ds_strcmp (name, "subnet")) { - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } else if (!omapi_ds_strcmp (name, "pool")) { return ISC_R_NOPERM; } else if (!omapi_ds_strcmp (name, "starts")) { @@ -277,7 +277,7 @@ isc_result_t dhcp_lease_set_value (omapi_object_t *h, u_int8_t oldflags; if (value->type != omapi_datatype_data) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; oldflags = lease->flags; lease->flags = (value->u.buffer.value[0] & EPHEMERAL_FLAGS) | @@ -291,11 +291,11 @@ isc_result_t dhcp_lease_set_value (omapi_object_t *h, } return ISC_R_SUCCESS; } else if (!omapi_ds_strcmp (name, "billing-class")) { - return ISC_R_UNCHANGED; /* XXX carefully allow change. */ + return DHCP_R_UNCHANGED; /* XXX carefully allow change. */ } else if (!omapi_ds_strcmp (name, "hardware-address")) { - return ISC_R_UNCHANGED; /* XXX take change. */ + return DHCP_R_UNCHANGED; /* XXX take change. */ } else if (!omapi_ds_strcmp (name, "hardware-type")) { - return ISC_R_UNCHANGED; /* XXX take change. */ + return DHCP_R_UNCHANGED; /* XXX take change. */ } else if (lease -> scope) { status = binding_scope_set_value (lease -> scope, 0, name, value); if (status == ISC_R_SUCCESS) { @@ -309,7 +309,7 @@ isc_result_t dhcp_lease_set_value (omapi_object_t *h, if (h -> inner && h -> inner -> type -> set_value) { status = ((*(h -> inner -> type -> set_value)) (h -> inner, id, name, value)); - if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED) + if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) return status; } @@ -335,7 +335,7 @@ isc_result_t dhcp_lease_get_value (omapi_object_t *h, omapi_object_t *id, isc_result_t status; if (h -> type != dhcp_type_lease) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; lease = (struct lease *)h; if (!omapi_ds_strcmp (name, "state")) @@ -400,7 +400,7 @@ isc_result_t dhcp_lease_get_value (omapi_object_t *h, omapi_object_t *id, if (status == ISC_R_SUCCESS) return status; } - return ISC_R_UNKNOWNATTRIBUTE; + return DHCP_R_UNKNOWNATTRIBUTE; } isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line) @@ -408,7 +408,7 @@ isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line) struct lease *lease; if (h -> type != dhcp_type_lease) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; lease = (struct lease *)h; if (lease -> uid) @@ -484,7 +484,7 @@ isc_result_t dhcp_lease_signal_handler (omapi_object_t *h, isc_result_t status; if (h -> type != dhcp_type_lease) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; lease = (struct lease *)h; if (!strcmp (name, "updated")) @@ -510,7 +510,7 @@ isc_result_t dhcp_lease_stuff_values (omapi_object_t *c, u_int8_t flagbuf; if (h -> type != dhcp_type_lease) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; lease = (struct lease *)h; /* Write out all the values. */ @@ -740,7 +740,7 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, struct lease *lease; if (!ref) - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; /* First see if we were sent a handle. */ status = omapi_get_value_str (ref, id, "handle", &tv); @@ -754,7 +754,7 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, /* Don't return the object if the type is wrong. */ if ((*lp) -> type != dhcp_type_lease) { omapi_object_dereference (lp, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } } @@ -773,7 +773,7 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, if (*lp && *lp != (omapi_object_t *)lease) { omapi_object_dereference (lp, MDL); lease_dereference (&lease, MDL); - return ISC_R_KEYCONFLICT; + return DHCP_R_KEYCONFLICT; } else if (!lease) { if (*lp) omapi_object_dereference (lp, MDL); @@ -799,7 +799,7 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, if (*lp && *lp != (omapi_object_t *)lease) { omapi_object_dereference (lp, MDL); lease_dereference (&lease, MDL); - return ISC_R_KEYCONFLICT; + return DHCP_R_KEYCONFLICT; } else if (!lease) { if (*lp) omapi_object_dereference (lp, MDL); @@ -807,7 +807,7 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, } else if (lease -> n_uid) { if (*lp) omapi_object_dereference (lp, MDL); - return ISC_R_MULTIPLE; + return DHCP_R_MULTIPLE; } else if (!*lp) { /* XXX fix so that hash lookup itself creates XXX the reference. */ @@ -842,7 +842,7 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, (tv -> value -> u.buffer.value[2] != 0)) { omapi_value_dereference (&tv, MDL); dfree (haddr, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } haddr[0] = tv -> value -> u.buffer.value[3]; @@ -852,7 +852,7 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, } else { omapi_value_dereference (&tv, MDL); dfree (haddr, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } omapi_value_dereference (&tv, MDL); @@ -872,7 +872,7 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, if (*lp && *lp != (omapi_object_t *)lease) { omapi_object_dereference (lp, MDL); lease_dereference (&lease, MDL); - return ISC_R_KEYCONFLICT; + return DHCP_R_KEYCONFLICT; } else if (!lease) { if (*lp) omapi_object_dereference (lp, MDL); @@ -881,7 +881,7 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, if (*lp) omapi_object_dereference (lp, MDL); lease_dereference (&lease, MDL); - return ISC_R_MULTIPLE; + return DHCP_R_MULTIPLE; } else if (!*lp) { /* XXX fix so that hash lookup itself creates XXX the reference. */ @@ -894,7 +894,7 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, /* If we get to here without finding a lease, no valid key was specified. */ if (!*lp) - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; return ISC_R_SUCCESS; } @@ -919,7 +919,7 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h, isc_result_t status; if (h -> type != dhcp_type_host) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; host = (struct host_decl *)h; /* XXX For now, we can only set these values on new host objects. @@ -938,7 +938,7 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h, value -> u.buffer.len); host -> name [value -> u.buffer.len] = 0; } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return ISC_R_SUCCESS; } @@ -962,7 +962,7 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h, group, MDL); group_object_dereference (&group, MDL); } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return ISC_R_SUCCESS; } @@ -973,13 +973,13 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h, value -> type == omapi_datatype_string)) { if (value -> u.buffer.len > (sizeof host -> interface.hbuf) - 1) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; memcpy (&host -> interface.hbuf [1], value -> u.buffer.value, value -> u.buffer.len); host -> interface.hlen = value -> u.buffer.len + 1; } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return ISC_R_SUCCESS; } @@ -988,7 +988,7 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h, if (value && (value -> type == omapi_datatype_data && value -> u.buffer.len == sizeof type)) { if (value -> u.buffer.len > sizeof type) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; memcpy (&type, value -> u.buffer.value, value -> u.buffer.len); @@ -996,7 +996,7 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h, } else if (value -> type == omapi_datatype_int) type = value -> u.integer; else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; host -> interface.hbuf [0] = type; return ISC_R_SUCCESS; } @@ -1016,7 +1016,7 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h, value -> u.buffer.len); host -> client_identifier.len = value -> u.buffer.len; } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return ISC_R_SUCCESS; } @@ -1043,7 +1043,7 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h, } data_string_forget (&ds, MDL); } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return ISC_R_SUCCESS; } @@ -1078,11 +1078,11 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h, (&host -> group -> statements, parse, &lose, context_any))) { end_parse (&parse); - return ISC_R_BADPARSE; + return DHCP_R_BADPARSE; } end_parse (&parse); } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return ISC_R_SUCCESS; } @@ -1096,11 +1096,11 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h, if (h -> inner && h -> inner -> type -> set_value) { status = ((*(h -> inner -> type -> set_value)) (h -> inner, id, name, value)); - if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED) + if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) return status; } - return ISC_R_UNKNOWNATTRIBUTE; + return DHCP_R_UNKNOWNATTRIBUTE; } @@ -1113,7 +1113,7 @@ isc_result_t dhcp_host_get_value (omapi_object_t *h, omapi_object_t *id, struct data_string ip_addrs; if (h -> type != dhcp_type_host) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; host = (struct host_decl *)h; if (!omapi_ds_strcmp (name, "ip-addresses")) { @@ -1170,7 +1170,7 @@ isc_result_t dhcp_host_get_value (omapi_object_t *h, omapi_object_t *id, if (status == ISC_R_SUCCESS) return status; } - return ISC_R_UNKNOWNATTRIBUTE; + return DHCP_R_UNKNOWNATTRIBUTE; } isc_result_t dhcp_host_destroy (omapi_object_t *h, const char *file, int line) @@ -1178,7 +1178,7 @@ isc_result_t dhcp_host_destroy (omapi_object_t *h, const char *file, int line) struct host_decl *host; if (h -> type != dhcp_type_host) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; host = (struct host_decl *)h; #if defined (DEBUG_MEMORY_LEAKAGE) || \ @@ -1213,14 +1213,14 @@ isc_result_t dhcp_host_signal_handler (omapi_object_t *h, int updatep = 0; if (h -> type != dhcp_type_host) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; host = (struct host_decl *)h; if (!strcmp (name, "updated")) { /* There must be a client identifier of some sort. */ if (host -> interface.hlen == 0 && !host -> client_identifier.len) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; if (!host -> name) { char hnbuf [64]; @@ -1262,7 +1262,7 @@ isc_result_t dhcp_host_stuff_values (omapi_object_t *c, struct data_string ip_addrs; if (h -> type != dhcp_type_host) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; host = (struct host_decl *)h; /* Write out all the values. */ @@ -1359,7 +1359,7 @@ isc_result_t dhcp_host_lookup (omapi_object_t **lp, struct host_decl *host; if (!ref) - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; /* First see if we were sent a handle. */ status = omapi_get_value_str (ref, id, "handle", &tv); @@ -1373,7 +1373,7 @@ isc_result_t dhcp_host_lookup (omapi_object_t **lp, /* Don't return the object if the type is wrong. */ if ((*lp) -> type != dhcp_type_host) { omapi_object_dereference (lp, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (((struct host_decl *)(*lp)) -> flags & HOST_DECL_DELETED) { omapi_object_dereference (lp, MDL); @@ -1393,7 +1393,7 @@ isc_result_t dhcp_host_lookup (omapi_object_t **lp, omapi_object_dereference (lp, MDL); if (host) host_dereference (&host, MDL); - return ISC_R_KEYCONFLICT; + return DHCP_R_KEYCONFLICT; } else if (!host || (host -> flags & HOST_DECL_DELETED)) { if (*lp) omapi_object_dereference (lp, MDL); @@ -1434,7 +1434,7 @@ isc_result_t dhcp_host_lookup (omapi_object_t **lp, (tv -> value -> u.buffer.value[2] != 0)) { omapi_value_dereference (&tv, MDL); dfree (haddr, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } haddr[0] = tv -> value -> u.buffer.value[3]; @@ -1444,7 +1444,7 @@ isc_result_t dhcp_host_lookup (omapi_object_t **lp, } else { omapi_value_dereference (&tv, MDL); dfree (haddr, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } omapi_value_dereference (&tv, MDL); @@ -1464,7 +1464,7 @@ isc_result_t dhcp_host_lookup (omapi_object_t **lp, omapi_object_dereference (lp, MDL); if (host) host_dereference (&host, MDL); - return ISC_R_KEYCONFLICT; + return DHCP_R_KEYCONFLICT; } else if (!host || (host -> flags & HOST_DECL_DELETED)) { if (*lp) omapi_object_dereference (lp, MDL); @@ -1506,7 +1506,7 @@ isc_result_t dhcp_host_lookup (omapi_object_t **lp, omapi_object_dereference (lp, MDL); if (host) host_dereference (&host, MDL); - return ISC_R_KEYCONFLICT; + return DHCP_R_KEYCONFLICT; } else if (!host || (host -> flags & HOST_DECL_DELETED)) { if (host) @@ -1537,7 +1537,7 @@ isc_result_t dhcp_host_lookup (omapi_object_t **lp, omapi_object_dereference (lp, MDL); if (host) host_dereference (&host, MDL); - return ISC_R_KEYCONFLICT; + return DHCP_R_KEYCONFLICT; } else if (!host || (host -> flags & HOST_DECL_DELETED)) { if (host) host_dereference (&host, MDL); @@ -1554,7 +1554,7 @@ isc_result_t dhcp_host_lookup (omapi_object_t **lp, /* If we get to here without finding a host, no valid key was specified. */ if (!*lp) - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; return ISC_R_SUCCESS; } @@ -1579,7 +1579,7 @@ isc_result_t dhcp_host_remove (omapi_object_t *lp, { struct host_decl *hp; if (lp -> type != dhcp_type_host) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; hp = (struct host_decl *)lp; #ifdef DEBUG_OMAPI @@ -1598,7 +1598,7 @@ isc_result_t dhcp_pool_set_value (omapi_object_t *h, isc_result_t status; if (h -> type != dhcp_type_pool) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; pool = (struct pool *)h; /* No values to set yet. */ @@ -1607,11 +1607,11 @@ isc_result_t dhcp_pool_set_value (omapi_object_t *h, if (h -> inner && h -> inner -> type -> set_value) { status = ((*(h -> inner -> type -> set_value)) (h -> inner, id, name, value)); - if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED) + if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) return status; } - return ISC_R_UNKNOWNATTRIBUTE; + return DHCP_R_UNKNOWNATTRIBUTE; } @@ -1623,7 +1623,7 @@ isc_result_t dhcp_pool_get_value (omapi_object_t *h, omapi_object_t *id, isc_result_t status; if (h -> type != dhcp_type_pool) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; pool = (struct pool *)h; /* No values to get yet. */ @@ -1635,7 +1635,7 @@ isc_result_t dhcp_pool_get_value (omapi_object_t *h, omapi_object_t *id, if (status == ISC_R_SUCCESS) return status; } - return ISC_R_UNKNOWNATTRIBUTE; + return DHCP_R_UNKNOWNATTRIBUTE; } isc_result_t dhcp_pool_destroy (omapi_object_t *h, const char *file, int line) @@ -1647,7 +1647,7 @@ isc_result_t dhcp_pool_destroy (omapi_object_t *h, const char *file, int line) #endif if (h -> type != dhcp_type_pool) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; pool = (struct pool *)h; #if defined (DEBUG_MEMORY_LEAKAGE) || \ @@ -1697,7 +1697,7 @@ isc_result_t dhcp_pool_signal_handler (omapi_object_t *h, int updatep = 0; if (h -> type != dhcp_type_pool) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; pool = (struct pool *)h; /* Can't write pools yet. */ @@ -1722,7 +1722,7 @@ isc_result_t dhcp_pool_stuff_values (omapi_object_t *c, isc_result_t status; if (h -> type != dhcp_type_pool) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; pool = (struct pool *)h; /* Can't stuff pool values yet. */ @@ -1746,7 +1746,7 @@ isc_result_t dhcp_pool_lookup (omapi_object_t **lp, /* If we get to here without finding a pool, no valid key was specified. */ if (!*lp) - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; return ISC_R_SUCCESS; } @@ -1809,7 +1809,7 @@ class_set_value (omapi_object_t *h, memcpy(class->name, value->u.buffer.value, value->u.buffer.len); } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return ISC_R_SUCCESS; } @@ -1830,7 +1830,7 @@ class_set_value (omapi_object_t *h, value->u.buffer.value, value->u.buffer.len); class->hash_string.len = value->u.buffer.len; } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return ISC_R_SUCCESS; } @@ -1850,7 +1850,7 @@ class_set_value (omapi_object_t *h, group_reference(&class->group, group->group, MDL); group_object_dereference(&group, MDL); } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return ISC_R_SUCCESS; } @@ -1874,9 +1874,9 @@ class_set_value (omapi_object_t *h, class->submatch->op = expr_hardware; } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return ISC_R_SUCCESS; } @@ -1887,9 +1887,9 @@ class_set_value (omapi_object_t *h, value->type == omapi_datatype_string) { /* XXXJAB support 'options' here. */ /* XXXJAB specifically 'bootfile-name' */ - return ISC_R_INVALIDARG; /* XXX tmp */ + return DHCP_R_INVALIDARG; /* XXX tmp */ } else - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return ISC_R_SUCCESS; } @@ -1899,11 +1899,11 @@ class_set_value (omapi_object_t *h, if (h->inner && h->inner->type->set_value) { status = ((*(h->inner->type->set_value)) (h->inner, id, name, value)); - if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED) + if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) return status; } - return ISC_R_UNKNOWNATTRIBUTE; + return DHCP_R_UNKNOWNATTRIBUTE; } @@ -1914,7 +1914,7 @@ isc_result_t dhcp_class_set_value (omapi_object_t *h, omapi_typed_data_t *value) { if (h -> type != dhcp_type_class) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return class_set_value(h, id, name, value); } @@ -1927,7 +1927,7 @@ isc_result_t dhcp_class_get_value (omapi_object_t *h, omapi_object_t *id, isc_result_t status; if (h -> type != dhcp_type_class) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; class = (struct class *)h; if (!omapi_ds_strcmp (name, "name")) @@ -1941,7 +1941,7 @@ isc_result_t dhcp_class_get_value (omapi_object_t *h, omapi_object_t *id, if (status == ISC_R_SUCCESS) return status; } - return ISC_R_UNKNOWNATTRIBUTE; + return DHCP_R_UNKNOWNATTRIBUTE; } isc_result_t dhcp_class_destroy (omapi_object_t *h, const char *file, int line) @@ -1949,7 +1949,7 @@ isc_result_t dhcp_class_destroy (omapi_object_t *h, const char *file, int line) struct class *class; if (h -> type != dhcp_type_class && h -> type != dhcp_type_subclass) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; class = (struct class *)h; #if defined (DEBUG_MEMORY_LEAKAGE) || \ @@ -2010,15 +2010,15 @@ class_signal_handler(omapi_object_t *h, if (!issubclass) { if (class -> name == 0 || strlen(class -> name) == 0) { - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } } else { if (class -> superclass == 0) { - return ISC_R_INVALIDARG; /* didn't give name */ + return DHCP_R_INVALIDARG; /* didn't give name */ } if (class -> hash_string.data == NULL) { - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } } @@ -2069,7 +2069,7 @@ isc_result_t dhcp_class_signal_handler (omapi_object_t *h, const char *name, va_list ap) { if (h -> type != dhcp_type_class) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return class_signal_handler(h, name, ap); } @@ -2082,7 +2082,7 @@ isc_result_t dhcp_class_stuff_values (omapi_object_t *c, isc_result_t status; if (h -> type != dhcp_type_class) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; class = (struct class *)h; /* Can't stuff class values yet. */ @@ -2133,14 +2133,14 @@ static isc_result_t class_lookup (omapi_object_t **lp, "hashstring", &hv); if (status != ISC_R_SUCCESS) { class_dereference(&class, MDL); - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; } if (hv -> value -> type != omapi_datatype_data && hv -> value -> type != omapi_datatype_string) { class_dereference(&class, MDL); omapi_value_dereference (&hv, MDL); - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; } class_hash_lookup (&subclass, class -> hash, @@ -2164,7 +2164,7 @@ static isc_result_t class_lookup (omapi_object_t **lp, /* Don't return the object if the type is wrong. */ if (class -> type != typewanted) { class_dereference (&class, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (class -> flags & CLASS_DECL_DELETED) { @@ -2176,7 +2176,7 @@ static isc_result_t class_lookup (omapi_object_t **lp, return ISC_R_SUCCESS; } - return ISC_R_NOKEYS; + return DHCP_R_NOKEYS; } @@ -2208,7 +2208,7 @@ isc_result_t dhcp_class_remove (omapi_object_t *lp, { struct class *cp; if (lp -> type != dhcp_type_class) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; cp = (struct class *)lp; #ifdef DEBUG_OMAPI @@ -2225,7 +2225,7 @@ isc_result_t dhcp_subclass_set_value (omapi_object_t *h, omapi_typed_data_t *value) { if (h -> type != dhcp_type_subclass) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return class_set_value(h, id, name, value); } @@ -2239,10 +2239,10 @@ isc_result_t dhcp_subclass_get_value (omapi_object_t *h, omapi_object_t *id, isc_result_t status; if (h -> type != dhcp_type_class) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; subclass = (struct class *)h; if (subclass -> name != 0) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* XXXJAB No values to get yet. */ @@ -2253,14 +2253,14 @@ isc_result_t dhcp_subclass_get_value (omapi_object_t *h, omapi_object_t *id, if (status == ISC_R_SUCCESS) return status; } - return ISC_R_UNKNOWNATTRIBUTE; + return DHCP_R_UNKNOWNATTRIBUTE; } isc_result_t dhcp_subclass_signal_handler (omapi_object_t *h, const char *name, va_list ap) { if (h -> type != dhcp_type_subclass) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; return class_signal_handler(h, name, ap); } @@ -2274,10 +2274,10 @@ isc_result_t dhcp_subclass_stuff_values (omapi_object_t *c, isc_result_t status; if (h -> type != dhcp_type_class) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; subclass = (struct class *)h; if (subclass -> name != 0) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; /* Can't stuff subclass values yet. */ @@ -2345,7 +2345,7 @@ isc_result_t dhcp_subclass_remove (omapi_object_t *lp, struct class *cp; if (lp -> type != dhcp_type_subclass) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; cp = (struct class *)lp; #ifdef DEBUG_OMAPI @@ -2374,12 +2374,12 @@ isc_result_t binding_scope_set_value (struct binding_scope *scope, int createp, bp = find_binding (scope, nname); if (!bp && !createp) { dfree (nname, MDL); - return ISC_R_UNKNOWNATTRIBUTE; + return DHCP_R_UNKNOWNATTRIBUTE; } if (!value) { dfree (nname, MDL); if (!bp) - return ISC_R_UNKNOWNATTRIBUTE; + return DHCP_R_UNKNOWNATTRIBUTE; binding_value_dereference (&bp -> value, MDL); return ISC_R_SUCCESS; } @@ -2411,7 +2411,7 @@ isc_result_t binding_scope_set_value (struct binding_scope *scope, int createp, case omapi_datatype_object: binding_value_dereference (&nv, MDL); dfree (nname, MDL); - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; } if (!bp) { @@ -2452,9 +2452,9 @@ isc_result_t binding_scope_get_value (omapi_value_t **value, bp = find_binding (scope, nname); dfree (nname, MDL); if (!bp) - return ISC_R_UNKNOWNATTRIBUTE; + return DHCP_R_UNKNOWNATTRIBUTE; if (!bp -> value) - return ISC_R_UNKNOWNATTRIBUTE; + return DHCP_R_UNKNOWNATTRIBUTE; switch (bp -> value -> type) { case binding_boolean: @@ -2484,7 +2484,7 @@ isc_result_t binding_scope_get_value (omapi_value_t **value, /* Can't return values for these two (yet?). */ case binding_dns: case binding_function: - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; default: log_fatal ("Impossible case at %s:%d.", MDL); diff --git a/server/salloc.c b/server/salloc.c index 9c015141..36597b91 100644 --- a/server/salloc.c +++ b/server/salloc.c @@ -111,7 +111,7 @@ isc_result_t dhcp_lease_free (omapi_object_t *lo, { struct lease *lease; if (lo -> type != dhcp_type_lease) - return ISC_R_INVALIDARG; + return DHCP_R_INVALIDARG; lease = (struct lease *)lo; memset (lease, 0, sizeof (struct lease)); lease -> next = free_leases; diff --git a/tests/t_api.c b/tests/t_api.c index 0211b834..23a4312a 100644 --- a/tests/t_api.c +++ b/tests/t_api.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: t_api.c,v 1.3 2009/01/22 00:43:58 sar Exp $ */ +/* $Id: t_api.c,v 1.4 2009/10/28 04:12:30 sar Exp $ */ /*! \file */ @@ -43,15 +43,15 @@ #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #ifdef DNS_SUPPORT #include -#include +#include #endif /* DNS_SUPPORT */ #ifndef BIND_SUPPORT diff --git a/util/bind.sh b/util/bind.sh new file mode 100644 index 00000000..88326207 --- /dev/null +++ b/util/bind.sh @@ -0,0 +1,73 @@ +#!/bin/sh +# +# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or 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: bind.sh,v 1.2 2009/10/28 04:12:30 sar Exp $ + +# Get the bind distribution for the libraries +# This script is used to build the DHCP distribution and shouldn't be shipped +# +# Usage: sh bind.sh +# +# Currently no arguments +# + +topdir=`pwd` +binddir=$topdir/bind + +case $# in + 1) + case "$1" in + 4.2.0) BINDTAG=v9_7_0b1 ;; + 4.1.2) BINDTAG=v9_7_0b1 ;; + *) echo "usage: sh bind.sh " >&2 + exit 1 + ;; + esac + ;; + *) echo "usage: sh bind.sh " >&2 + exit 1 + ;; +esac + +# Delete all previous bind stuff +rm -rf bind + +# Make and move to our directory for all things bind +mkdir $binddir +cd $binddir + +# Get the bind release kit shell script +cvs checkout -p -r $BINDTAG bind9/util/kit.sh > kit.sh + +# Create the bind tarball, which has the side effect of +# setting up the bind directory we will use for building +# the export libraries +sh kit.sh $BINDTAG $binddir + +. ./version.tmp + +version=${MAJORVER}.${MINORVER}.${PATCHVER}${RELEASETYPE}${RELEASEVER} +bindsrcdir=bind-$version + +# move the tar file to a known place for use by the make dist command +mv bind-9.7*.tar.gz bind.tar.gz + +# temporary hack to allow testing when using snapshots +#mv $binddir/bind-9.7* $binddir/$bindsrcdir + +# Run the script to build and install the export libraries +sh $topdir/util/bindlib.sh $binddir $bindsrcdir + diff --git a/util/bindcus.sh b/util/bindcus.sh new file mode 100644 index 00000000..6f0388ac --- /dev/null +++ b/util/bindcus.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# +# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or 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: bindcus.sh,v 1.2 2009/10/28 04:12:30 sar Exp $ + +# Configure and build the bind libraries for use by DHCP +# +# Usage: sh bindcus.sh +# +# Currently no arguments +# + + +topdir=`pwd` +binddir=$topdir/bind +cd bind + +. ./version.tmp +version=${MAJORVER}.${MINORVER}.${PATCHVER}${RELEASETYPE}${RELEASEVER} +bindsrcdir=bind-$version + +# Extract the source from the tarball +gunzip -c bind.tar.gz | tar xf - + +# Run the script to build and install the export libraries +sh $topdir/util/bindlib.sh $binddir $bindsrcdir diff --git a/util/bindlib.sh b/util/bindlib.sh new file mode 100644 index 00000000..f755deec --- /dev/null +++ b/util/bindlib.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# +# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or 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: bindlib.sh,v 1.2 2009/10/28 04:12:30 sar Exp $ + +# Configure, build and install the bind export libraries for use by DHCP +# +# Usage: sh bindlib.sh +# The intention is for this script to be called by other scrips +# (bind.sh or bindcus.sh) rather than be called directly. +# +# = directory for bind stuff within DHCP, typically +# /bind +# +# = directory for the unpacked bind source code +# typically /bind/bind- +# + +binddir="$1" +bindsrcdir="$2" + +# Configure the export libraries +cd $bindsrcdir +./configure --without-libxml2 --enable-exportlib --enable-threads=no --with-export-includedir=$binddir/include --with-export-libdir=$binddir/lib > $binddir/configure.log + +# Build the export librares +cd lib/export +gmake > $binddir/build.log + +# Install the libraries and includes +gmake install > $binddir/install.log