From: Marcin Siodelski Date: Wed, 23 Jan 2013 07:41:38 +0000 (+0100) Subject: [master] Merge branch 'trac2637' X-Git-Tag: bind10-1.0.0-rc-release~29^2~1^2~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=91aa998226f1f91a232f2be59a53c9568c4ece77;p=thirdparty%2Fkea.git [master] Merge branch 'trac2637' Conflicts: src/bin/dhcp4/config_parser.cc src/bin/dhcp6/config_parser.cc src/lib/dhcpsrv/dhcpsrv_messages.mes src/lib/dhcpsrv/memfile_lease_mgr.cc --- 91aa998226f1f91a232f2be59a53c9568c4ece77 diff --cc src/bin/dhcp6/ctrl_dhcp6_srv.cc index a1fe4e5f9c,f41e240eec..e4e17f1eaa --- a/src/bin/dhcp6/ctrl_dhcp6_srv.cc +++ b/src/bin/dhcp6/ctrl_dhcp6_srv.cc @@@ -42,22 -42,66 +42,65 @@@ using namespace std namespace isc { namespace dhcp { - ControlledDhcpv6Srv* ControlledDhcpv6Srv::server_ = NULL; + ConstElementPtr + ControlledDhcpv6Srv::dhcp6StubConfigHandler(ConstElementPtr) { + // This configuration handler is intended to be used only + // when the initial configuration comes in. To receive this + // configuration a pointer to this handler must be passed + // using ModuleCCSession constructor. This constructor will + // invoke the handler and will store the configuration for + // the configuration session when the handler returns success. + // Since this configuration is partial we just pretend to + // parse it and always return success. The function that + // initiates the session must get the configuration on its + // own using getFullConfig. + return (isc::config::createAnswer(0, "Configuration accepted.")); + } + ConstElementPtr ControlledDhcpv6Srv::dhcp6ConfigHandler(ConstElementPtr new_config) { - LOG_DEBUG(dhcp6_logger, DBG_DHCP6_COMMAND, DHCP6_CONFIG_UPDATE) - .arg(new_config->str()); - if (server_) { - return (configureDhcp6Server(*server_, new_config)); + if (!server_ || !server_->config_session_) { + // That should never happen as we install config_handler + // after we instantiate the server. + ConstElementPtr answer = + isc::config::createAnswer(1, "Configuration rejected," + " server is during startup/shutdown phase."); + return (answer); } - // That should never happen as we install config_handler after we instantiate - // the server. - ConstElementPtr answer = isc::config::createAnswer(1, - "Configuration rejected, server is during startup/shutdown phase."); - return (answer); + // The configuration passed to this handler function is partial. + // In other words, it just includes the values being modified. + // In the same time, there are dependencies between various + // DHCP configuration parsers. For example: the option value can + // be set if the definition of this option is set. If someone removes + // an existing option definition then the partial configuration that + // removes that definition is triggered while a relevant option value + // may remain configured. This eventually results in the DHCP server + // configuration being in the inconsistent state. + // In order to work around this problem we need to merge the new + // configuration with the existing (full) configuration. + + // Let's create a new object that will hold the merged configuration. + boost::shared_ptr merged_config(new MapElement()); + // Let's get the existing configuration. + ConstElementPtr full_config = server_->config_session_->getFullConfig(); + // The full_config and merged_config should be always non-NULL + // but to provide some level of exception safety we check that they + // really are (in case we go out of memory). + if (full_config && merged_config) { + merged_config->setValue(full_config->mapValue()); + + // Merge an existing and new configuration. + isc::data::merge(merged_config, new_config); + LOG_DEBUG(dhcp6_logger, DBG_DHCP6_COMMAND, DHCP6_CONFIG_UPDATE) + .arg(merged_config->str()); + } + + // Configure the server. + return (configureDhcp6Server(*server_, merged_config)); } ConstElementPtr