diff options
-rw-r--r-- | RELNOTES | 10 | ||||
-rw-r--r-- | common/tables.c | 10 | ||||
-rw-r--r-- | includes/tree.h | 2 | ||||
-rw-r--r-- | server/dhcp.c | 70 | ||||
-rw-r--r-- | server/stables.c | 4 |
5 files changed, 93 insertions, 3 deletions
@@ -98,6 +98,16 @@ suggested fixes to <dhcp-users@isc.org>. 'address' parameter (the server's local address) did not resolve to an IPv4 address. +- The minimum site code value was set to 224 in 3.1.0 to track RFC3942. This + broke a lot of legacy site local configurations. The new code in place will + track site local space minimum option codes and logs a warning to encourage + updates and exploration of site local code migration problems. Option + codes less than 128 in site local spaces remain inaccessible. + +- A possible relay agent option bug was repaired where random server + initialization state may have been used to signal the relay agent + information options sub-option code for the 'END' of the option space. + Changes since 4.0.0b3 - The reverse dns name for PTR updates on IPv6 addresses has been fixed to diff --git a/common/tables.c b/common/tables.c index 46874207..9259332d 100644 --- a/common/tables.c +++ b/common/tables.c @@ -961,6 +961,7 @@ void initialize_common_option_spaces() dhcp_universe.store_tag = putUChar; dhcp_universe.get_length = getUChar; dhcp_universe.store_length = putUChar; + dhcp_universe.site_code_min = 0; dhcp_universe.end = DHO_END; dhcp_universe.index = universe_count++; universes [dhcp_universe.index] = &dhcp_universe; @@ -1001,6 +1002,7 @@ void initialize_common_option_spaces() nwip_universe.store_tag = putUChar; nwip_universe.get_length = getUChar; nwip_universe.store_length = putUChar; + nwip_universe.site_code_min = 0; nwip_universe.end = 0; code = DHO_NWIP_SUBOPTIONS; nwip_universe.enc_opt = NULL; @@ -1046,6 +1048,7 @@ void initialize_common_option_spaces() fqdn_universe.store_tag = putUChar; fqdn_universe.get_length = getUChar; fqdn_universe.store_length = putUChar; + fqdn_universe.site_code_min = 0; fqdn_universe.end = 0; fqdn_universe.index = universe_count++; code = DHO_FQDN; @@ -1093,6 +1096,7 @@ void initialize_common_option_spaces() vendor_class_universe.store_tag = putULong; vendor_class_universe.get_length = getUChar; vendor_class_universe.store_length = putUChar; + vendor_class_universe.site_code_min = 0; vendor_class_universe.end = 0; code = DHO_VIVCO_SUBOPTIONS; vendor_class_universe.enc_opt = NULL; @@ -1139,6 +1143,7 @@ void initialize_common_option_spaces() vendor_universe.store_tag = putULong; vendor_universe.get_length = getUChar; vendor_universe.store_length = putUChar; + vendor_universe.site_code_min = 0; vendor_universe.end = 0; code = DHO_VIVSO_SUBOPTIONS; vendor_universe.enc_opt = NULL; @@ -1185,6 +1190,7 @@ void initialize_common_option_spaces() isc_universe.store_tag = putUShort; isc_universe.get_length = getUShort; isc_universe.store_length = putUShort; + isc_universe.site_code_min = 0; isc_universe.end = 0; code = VENDOR_ISC_SUBOPTIONS; isc_universe.enc_opt = NULL; @@ -1230,6 +1236,7 @@ void initialize_common_option_spaces() dhcpv6_universe.store_tag = putUShort; dhcpv6_universe.get_length = getUShort; dhcpv6_universe.store_length = putUShort; + dhcpv6_universe.site_code_min = 0; /* DHCPv6 has no END option. */ dhcpv6_universe.end = 0x00; dhcpv6_universe.index = universe_count++; @@ -1270,6 +1277,7 @@ void initialize_common_option_spaces() vsio_universe.store_tag = putULong; vsio_universe.get_length = NULL; vsio_universe.store_length = NULL; + vsio_universe.site_code_min = 0; /* No END option. */ vsio_universe.end = 0x00; code = D6O_VENDOR_OPTS; @@ -1310,6 +1318,7 @@ void initialize_common_option_spaces() isc6_universe.store_tag = putULong; isc6_universe.get_length = NULL; isc6_universe.store_length = NULL; + isc6_universe.site_code_min = 0; /* No END option. */ isc6_universe.end = 0x00; code = 2495; @@ -1353,6 +1362,7 @@ void initialize_common_option_spaces() fqdn6_universe.store_tag = NULL; fqdn6_universe.get_length = NULL; fqdn6_universe.store_length = NULL; + fqdn6_universe.site_code_min = 0; fqdn6_universe.end = 0; fqdn6_universe.index = universe_count++; code = D6O_CLIENT_FQDN; diff --git a/includes/tree.h b/includes/tree.h index ef8f3baf..2df11ceb 100644 --- a/includes/tree.h +++ b/includes/tree.h @@ -334,7 +334,7 @@ struct universe { u_int32_t (*get_length) (const unsigned char *); void (*store_length) PROTO ((unsigned char *, u_int32_t)); int tag_size, length_size; - unsigned end; + unsigned site_code_min, end; option_name_hash_t *name_hash; option_code_hash_t *code_hash; struct option *enc_opt; diff --git a/server/dhcp.c b/server/dhcp.c index 65c55860..3b8d2cb4 100644 --- a/server/dhcp.c +++ b/server/dhcp.c @@ -39,6 +39,10 @@ int outstanding_pings; static char dhcp_message [256]; +static int site_code_min; + +static int find_min_site_code(struct universe *); +static isc_result_t lowest_site_code(const void *, unsigned, void *); static const char *dhcp_type_names [] = { "DHCPDISCOVER", @@ -1136,7 +1140,7 @@ void dhcpinform (packet, ms_nulltp) } options -> site_universe = u -> index; - options -> site_code_min = 224; /* From RFC3942 */ + options->site_code_min = find_min_site_code(u); data_string_forget (&d1, MDL); } else { options -> site_universe = dhcp_universe.index; @@ -2732,7 +2736,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp) } state -> options -> site_universe = u -> index; - state -> options -> site_code_min = 224; /* From RFC3942 */ + state->options->site_code_min = find_min_site_code(u); data_string_forget (&d1, MDL); } else { state -> options -> site_code_min = 0; @@ -4028,3 +4032,65 @@ get_server_source_address(struct in_addr *from, } } +/* + * Look for the lowest numbered site code number and + * apply a log warning if it is less than 224. Do not + * permit site codes less than 128 (old code never did). + * + * Note that we could search option codes 224 down to 128 + * on the hash table, but the table is (probably) smaller + * than that if it was declared as a standalone table with + * defaults. So we traverse the option code hash. + */ +static int +find_min_site_code(struct universe *u) +{ + if (u->site_code_min) + return u->site_code_min; + + /* + * Note that site_code_min has to be global as we can't pass an + * argument through hash_foreach(). The value 224 is taken from + * RFC 3942. + */ + site_code_min = 224; + option_code_hash_foreach(u->code_hash, lowest_site_code); + + if (site_code_min < 224) { + log_error("WARNING: site-local option codes less than 224 have " + "been deprecated by RFC3942. You have options " + "listed in site local space %s that number as low as " + "%d. Please investigate if these should be declared " + "as regular options rather than site-local options, " + "or migrated up past 224.", + u->name, site_code_min); + } + + /* + * don't even bother logging, this is just silly, and never worked + * on any old version of software. + */ + if (site_code_min < 128) + site_code_min = 128; + + /* + * Cache the determined minimum site code on the universe structure. + * Note that due to the < 128 check above, a value of zero is + * impossible. + */ + u->site_code_min = site_code_min; + + return site_code_min; +} + +static isc_result_t +lowest_site_code(const void *key, unsigned len, void *object) +{ + struct option *option = object; + + if (option->code < site_code_min) + site_code_min = option->code; + + return ISC_R_SUCCESS; +} + diff --git a/server/stables.c b/server/stables.c index 3e1dffdc..a2d76c79 100644 --- a/server/stables.c +++ b/server/stables.c @@ -347,6 +347,8 @@ void initialize_server_option_spaces() agent_universe.store_tag = putUChar; agent_universe.get_length = getUChar; agent_universe.store_length = putUChar; + agent_universe.site_code_min = 0; + agent_universe.end = 0; universes [agent_universe.index] = &agent_universe; if (!option_name_new_hash(&agent_universe.name_hash, AGENT_HASH_SIZE, MDL) || @@ -385,6 +387,8 @@ void initialize_server_option_spaces() server_universe.tag_size = 4; server_universe.store_tag = putUChar; server_universe.store_length = putUChar; + server_universe.site_code_min = 0; + server_universe.end = 0; server_universe.index = universe_count++; universes [server_universe.index] = &server_universe; if (!option_name_new_hash(&server_universe.name_hash, |