From 86f1d4b72395f9102b974cdd1fb4e40599530a64 Mon Sep 17 00:00:00 2001 From: David Hankins Date: Thu, 16 Jul 2009 18:02:28 +0000 Subject: [PATCH] - Versions 3.0.x syntax with multiple name->code option definitions is now supported. Note that, similarly to 3.0.x, for by-code lookups only the last option definition is used. [ISC-Bugs #17613] --- RELNOTES | 4 ++++ client/clparse.c | 13 +++++++++++++ common/parse.c | 11 ++++++++++- server/confpars.c | 14 ++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/RELNOTES b/RELNOTES index 6c349cff..ed566e34 100644 --- a/RELNOTES +++ b/RELNOTES @@ -200,6 +200,10 @@ work on other platforms. Please report any problems and suggested fixes to one of either of those). This resolves a bug where dual stack clients would not be able to regain their names after either expiration event. +- Versions 3.0.x syntax with multiple name->code option definitions is now + supported. Note that, similarly to 3.0.x, for by-code lookups only the + last option definition is used. + Changes since 4.1.0a1 - Corrected list of failover state values in dhcpd man page. diff --git a/client/clparse.c b/client/clparse.c index 2cab5f93..0e951bcc 100644 --- a/client/clparse.c +++ b/client/clparse.c @@ -502,6 +502,7 @@ void parse_client_statement (cfile, ip, config) return; } + known = 0; status = parse_option_name(cfile, 1, &known, &option); if (status != ISC_R_SUCCESS || option == NULL) return; @@ -521,6 +522,18 @@ void parse_client_statement (cfile, ip, config) option_dereference(&option, MDL); return; } + + /* + * If the option was known, remove it from the code and name + * hash tables before redefining it. + */ + if (known) { + option_name_hash_delete(option->universe->name_hash, + option->name, 0, MDL); + option_code_hash_delete(option->universe->code_hash, + &option->code, 0, MDL); + } + parse_option_code_definition(cfile, option); option_dereference(&option, MDL); return; diff --git a/common/parse.c b/common/parse.c index feaec7df..55f5cffb 100644 --- a/common/parse.c +++ b/common/parse.c @@ -1757,9 +1757,18 @@ int parse_option_code_definition (cfile, option) oldopt = NULL; option_code_hash_lookup(&oldopt, option->universe->code_hash, &option->code, 0, MDL); - if (oldopt) { + if (oldopt != NULL) { + /* + * XXX: This illegalizes a configuration syntax that was + * valid in 3.0.x, where multiple name->code mappings are + * given, but only one code->name mapping survives. It is + * unclear what can or should be done at this point, but it + * seems best to retain 3.0.x behaviour for upgrades to go + * smoothly. + * option_name_hash_delete(option->universe->name_hash, oldopt->name, 0, MDL); + */ option_code_hash_delete(option->universe->code_hash, &oldopt->code, 0, MDL); diff --git a/server/confpars.c b/server/confpars.c index 2ccd8972..63280ac2 100644 --- a/server/confpars.c +++ b/server/confpars.c @@ -724,6 +724,20 @@ int parse_statement (cfile, group, type, host_decl, declaration) break; } next_token (&val, (unsigned *)0, cfile); + + /* + * If the option was known, remove it from the + * code and name hashes before redefining it. + */ + if (known) { + option_name_hash_delete( + option->universe->name_hash, + option->name, 0, MDL); + option_code_hash_delete( + option->universe->code_hash, + &option->code, 0, MDL); + } + parse_option_code_definition(cfile, option); option_dereference(&option, MDL); return declaration;