: storage_(NULL),
param_name_(param_name),
value_(false) {
+ // Empty parameter name is invalid.
+ if (param_name_.empty()) {
+ isc_throw(isc::dhcp::Dhcp4ConfigError, "parser logic error:"
+ << "empty parameter name provided");
+ }
}
/// @brief Parse a boolean value.
///
/// @param param_name name of the parameter for which the
/// parser is created.
- static Dhcp4ConfigParser* Factory(const std::string& param_name) {
+ static Dhcp4ConfigParser* factory(const std::string& param_name) {
return (new BooleanParser(param_name));
}
Uint32Parser(const std::string& param_name)
: storage_(&uint32_defaults),
param_name_(param_name) {
+ // Empty parameter name is invalid.
+ if (param_name_.empty()) {
+ isc_throw(Dhcp4ConfigError, "parser logic error:"
+ << "empty parameter name provided");
+ }
}
/// @brief Parses configuration configuration parameter as uint32_t.
/// or the parameter name is empty.
virtual void build(ConstElementPtr value) {
if (param_name_.empty()) {
- isc_throw(BadValue, "parser logic error:"
+ isc_throw(Dhcp4ConfigError, "parser logic error:"
<< "empty parameter name provided");
}
/// @brief factory that constructs Uint32Parser objects
///
/// @param param_name name of the parameter to be parsed
- static Dhcp4ConfigParser* Factory(const std::string& param_name) {
+ static Dhcp4ConfigParser* factory(const std::string& param_name) {
return (new Uint32Parser(param_name));
}
/// @param param_name name of the configuration parameter being parsed
StringParser(const std::string& param_name)
:storage_(&string_defaults), param_name_(param_name) {
+ // Empty parameter name is invalid.
+ if (param_name_.empty()) {
+ isc_throw(Dhcp4ConfigError, "parser logic error:"
+ << "empty parameter name provided");
+ }
}
/// @brief parses parameter value
/// @brief factory that constructs StringParser objects
///
/// @param param_name name of the parameter to be parsed
- static Dhcp4ConfigParser* Factory(const std::string& param_name) {
+ static Dhcp4ConfigParser* factory(const std::string& param_name) {
return (new StringParser(param_name));
}
/// @brief factory that constructs InterfaceListConfigParser objects
///
/// @param param_name name of the parameter to be parsed
- static Dhcp4ConfigParser* Factory(const std::string& param_name) {
+ static Dhcp4ConfigParser* factory(const std::string& param_name) {
return (new InterfaceListConfigParser(param_name));
}
/// @brief factory that constructs PoolParser objects
///
/// @param param_name name of the parameter to be parsed
- static Dhcp4ConfigParser* Factory(const std::string& param_name) {
+ static Dhcp4ConfigParser* factory(const std::string& param_name) {
return (new PoolParser(param_name));
}
ParserPtr parser;
if (param.first == "name") {
boost::shared_ptr<StringParser>
- name_parser(dynamic_cast<StringParser*>(StringParser::Factory(param.first)));
+ name_parser(dynamic_cast<StringParser*>(StringParser::factory(param.first)));
if (name_parser) {
name_parser->setStorage(&string_values_);
parser = name_parser;
}
} else if (param.first == "code") {
boost::shared_ptr<Uint32Parser>
- code_parser(dynamic_cast<Uint32Parser*>(Uint32Parser::Factory(param.first)));
+ code_parser(dynamic_cast<Uint32Parser*>(Uint32Parser::factory(param.first)));
if (code_parser) {
code_parser->setStorage(&uint32_values_);
parser = code_parser;
}
} else if (param.first == "data") {
boost::shared_ptr<StringParser>
- value_parser(dynamic_cast<StringParser*>(StringParser::Factory(param.first)));
+ value_parser(dynamic_cast<StringParser*>(StringParser::factory(param.first)));
if (value_parser) {
value_parser->setStorage(&string_values_);
parser = value_parser;
}
} else if (param.first == "csv-format") {
boost::shared_ptr<BooleanParser>
- value_parser(dynamic_cast<BooleanParser*>(BooleanParser::Factory(param.first)));
+ value_parser(dynamic_cast<BooleanParser*>(BooleanParser::factory(param.first)));
if (value_parser) {
value_parser->setStorage(&boolean_values_);
parser = value_parser;
/// @param param_name param name.
///
/// @return DhcpConfigParser object.
- static Dhcp4ConfigParser* Factory(const std::string& param_name) {
+ static Dhcp4ConfigParser* factory(const std::string& param_name) {
return (new OptionDataListParser(param_name));
}
isc_throw(Dhcp4ConfigError,
"Mandatory subnet definition in subnet missing");
}
+ // Remove any spaces or tabs.
string subnet_txt = it->second;
boost::erase_all(subnet_txt, " ");
boost::erase_all(subnet_txt, "\t");
+ // The subnet format is prefix/len. We are going to extract
+ // the prefix portion of a subnet string to create IOAddress
+ // object from it. IOAddress will be passed to the Subnet's
+ // constructor later on. In order to extract the prefix we
+ // need to get all characters preceding "/".
size_t pos = subnet_txt.find("/");
if (pos == string::npos) {
isc_throw(Dhcp4ConfigError,
"Invalid subnet syntax (prefix/len expected):" << it->second);
}
+
+ // Try to create the address object. It also validates that
+ // the address syntax is ok.
IOAddress addr(subnet_txt.substr(0, pos));
uint8_t len = boost::lexical_cast<unsigned int>(subnet_txt.substr(pos + 1));
+ // Get all 'time' parameters using inheritance.
+ // If the subnet-specific value is defined then use it, else
+ // use the global value. The global value must always be
+ // present. If it is not, it is an internal error and exception
+ // is thrown.
Triplet<uint32_t> t1 = getParam("renew-timer");
Triplet<uint32_t> t2 = getParam("rebind-timer");
Triplet<uint32_t> valid = getParam("valid-lifetime");
Dhcp4ConfigParser* createSubnet4ConfigParser(const std::string& config_id) {
FactoryMap factories;
- factories["valid-lifetime"] = Uint32Parser::Factory;
- factories["renew-timer"] = Uint32Parser::Factory;
- factories["rebind-timer"] = Uint32Parser::Factory;
- factories["subnet"] = StringParser::Factory;
- factories["pool"] = PoolParser::Factory;
- factories["option-data"] = OptionDataListParser::Factory;
+ factories["valid-lifetime"] = Uint32Parser::factory;
+ factories["renew-timer"] = Uint32Parser::factory;
+ factories["rebind-timer"] = Uint32Parser::factory;
+ factories["subnet"] = StringParser::factory;
+ factories["pool"] = PoolParser::factory;
+ factories["option-data"] = OptionDataListParser::factory;
FactoryMap::iterator f = factories.find(config_id);
if (f == factories.end()) {
/// @brief Returns Subnet4ListConfigParser object
/// @param param_name name of the parameter
/// @return Subnets4ListConfigParser object
- static Dhcp4ConfigParser* Factory(const std::string& param_name) {
+ static Dhcp4ConfigParser* factory(const std::string& param_name) {
return (new Subnets4ListConfigParser(param_name));
}
Dhcp4ConfigParser* createGlobalDhcp4ConfigParser(const std::string& config_id) {
FactoryMap factories;
- factories["valid-lifetime"] = Uint32Parser::Factory;
- factories["renew-timer"] = Uint32Parser::Factory;
- factories["rebind-timer"] = Uint32Parser::Factory;
- factories["interface"] = InterfaceListConfigParser::Factory;
- factories["subnet4"] = Subnets4ListConfigParser::Factory;
- factories["option-data"] = OptionDataListParser::Factory;
- factories["version"] = StringParser::Factory;
+ factories["valid-lifetime"] = Uint32Parser::factory;
+ factories["renew-timer"] = Uint32Parser::factory;
+ factories["rebind-timer"] = Uint32Parser::factory;
+ factories["interface"] = InterfaceListConfigParser::factory;
+ factories["subnet4"] = Subnets4ListConfigParser::factory;
+ factories["option-data"] = OptionDataListParser::factory;
+ factories["version"] = StringParser::factory;
FactoryMap::iterator f = factories.find(config_id);
if (f == factories.end()) {
ParserCollection dependent_parsers;
// The subnet parsers implement data inheritance by directly
- // accesing global storages. For this reason the global data
+ // accessing global storage. For this reason the global data
// parsers must store the parsed data into global storages
- // immediatelly. This may cause data inconsistency if the
- // parsing operation fails after the global storage have been
- // already modified. We need to preserve the original global
- // data here so as we can rollback changes when an error occurs.
+ // immediately. This may cause data inconsistency if the
+ // parsing operation fails after the global storage has been
+ // modified. We need to preserve the original global data here
+ // so as we can rollback changes when an error occurs.
Uint32Storage uint32_local(uint32_defaults);
StringStorage string_local(string_defaults);
OptionStorage option_local(option_defaults);
try {
- // Iterate over all independent parsers first (all but subnet6)
+ // Iterate over all independent parsers first (all but subnet4)
// and try to parse the data.
BOOST_FOREACH(ConfigPair config_pair, config_set->mapValue()) {
- ParserPtr parser(createGlobalDhcp4ConfigParser(config_pair.first));
if (config_pair.first != "subnet4") {
+ ParserPtr parser(createGlobalDhcp4ConfigParser(config_pair.first));
independent_parsers.push_back(parser);
parser->build(config_pair.second);
// The commit operation here may modify the global storage
// Process dependent configuration data.
BOOST_FOREACH(ConfigPair config_pair, config_set->mapValue()) {
- ParserPtr parser(createGlobalDhcp4ConfigParser(config_pair.first));
if (config_pair.first == "subnet4") {
+ ParserPtr parser(createGlobalDhcp4ConfigParser(config_pair.first));
dependent_parsers.push_back(parser);
parser->build(config_pair.second);
}
/// @brief factory that constructs DebugParser objects
///
/// @param param_name name of the parameter to be parsed
- static DhcpConfigParser* Factory(const std::string& param_name) {
+ static DhcpConfigParser* factory(const std::string& param_name) {
return (new DebugParser(param_name));
}
: storage_(NULL),
param_name_(param_name),
value_(false) {
+ // Empty parameter name is invalid.
+ if (param_name_.empty()) {
+ isc_throw(isc::dhcp::Dhcp6ConfigError, "parser logic error:"
+ << "empty parameter name provided");
+ }
}
/// @brief Parse a boolean value.
///
/// @param param_name name of the parameter for which the
/// parser is created.
- static DhcpConfigParser* Factory(const std::string& param_name) {
+ static DhcpConfigParser* factory(const std::string& param_name) {
return (new BooleanParser(param_name));
}
Uint32Parser(const std::string& param_name)
: storage_(&uint32_defaults),
param_name_(param_name) {
+ // Empty parameter name is invalid.
+ if (param_name_.empty()) {
+ isc_throw(Dhcp6ConfigError, "parser logic error:"
+ << "empty parameter name provided");
+ }
}
/// @brief Parses configuration configuration parameter as uint32_t.
/// @brief Factory that constructs Uint32Parser objects.
///
/// @param param_name name of the parameter to be parsed.
- static DhcpConfigParser* Factory(const std::string& param_name) {
+ static DhcpConfigParser* factory(const std::string& param_name) {
return (new Uint32Parser(param_name));
}
StringParser(const std::string& param_name)
: storage_(&string_defaults),
param_name_(param_name) {
+ // Empty parameter name is invalid.
+ if (param_name_.empty()) {
+ isc_throw(Dhcp6ConfigError, "parser logic error:"
+ << "empty parameter name provided");
+ }
}
/// @brief parses parameter value
/// @brief Factory that constructs StringParser objects
///
/// @param param_name name of the parameter to be parsed
- static DhcpConfigParser* Factory(const std::string& param_name) {
+ static DhcpConfigParser* factory(const std::string& param_name) {
return (new StringParser(param_name));
}
/// @brief factory that constructs InterfaceListConfigParser objects
///
/// @param param_name name of the parameter to be parsed
- static DhcpConfigParser* Factory(const std::string& param_name) {
+ static DhcpConfigParser* factory(const std::string& param_name) {
return (new InterfaceListConfigParser(param_name));
}
/// (setStorage() not called)
void build(ConstElementPtr pools_list) {
- using namespace isc::dhcp;
-
// setStorage() should have been called before build
if (!pools_) {
isc_throw(isc::InvalidOperation, "parser logic error: no pool storage set,"
/// @brief factory that constructs PoolParser objects
///
/// @param param_name name of the parameter to be parsed
- static DhcpConfigParser* Factory(const std::string& param_name) {
+ static DhcpConfigParser* factory(const std::string& param_name) {
return (new PoolParser(param_name));
}
/// @throw isc::BadValue if option data storage is invalid.
virtual void build(ConstElementPtr option_data_entries) {
- using namespace isc::dhcp;
-
if (options_ == NULL) {
isc_throw(isc::InvalidOperation, "Parser logic error: storage must be set before "
"parsing option data.");
ParserPtr parser;
if (param.first == "name") {
boost::shared_ptr<StringParser>
- name_parser(dynamic_cast<StringParser*>(StringParser::Factory(param.first)));
+ name_parser(dynamic_cast<StringParser*>(StringParser::factory(param.first)));
if (name_parser) {
name_parser->setStorage(&string_values_);
parser = name_parser;
}
} else if (param.first == "code") {
boost::shared_ptr<Uint32Parser>
- code_parser(dynamic_cast<Uint32Parser*>(Uint32Parser::Factory(param.first)));
+ code_parser(dynamic_cast<Uint32Parser*>(Uint32Parser::factory(param.first)));
if (code_parser) {
code_parser->setStorage(&uint32_values_);
parser = code_parser;
}
} else if (param.first == "data") {
boost::shared_ptr<StringParser>
- value_parser(dynamic_cast<StringParser*>(StringParser::Factory(param.first)));
+ value_parser(dynamic_cast<StringParser*>(StringParser::factory(param.first)));
if (value_parser) {
value_parser->setStorage(&string_values_);
parser = value_parser;
}
} else if (param.first == "csv-format") {
boost::shared_ptr<BooleanParser>
- value_parser(dynamic_cast<BooleanParser*>(BooleanParser::Factory(param.first)));
+ value_parser(dynamic_cast<BooleanParser*>(BooleanParser::factory(param.first)));
if (value_parser) {
value_parser->setStorage(&boolean_values_);
parser = value_parser;
/// are invalid.
void createOption() {
- using namespace isc::dhcp;
-
// Option code is held in the uint32_t storage but is supposed to
// be uint16_t value. We need to check that value in the configuration
// does not exceed range of uint16_t and is not zero.
/// @param param_name param name.
///
/// @return DhcpConfigParser object.
- static DhcpConfigParser* Factory(const std::string& param_name) {
+ static DhcpConfigParser* factory(const std::string& param_name) {
return (new OptionDataListParser(param_name));
}
/// @throw isc::Dhcp6ConfigError if subnet configuration parsing failed.
void build(ConstElementPtr subnet) {
- using namespace isc::dhcp;
-
BOOST_FOREACH(ConfigPair param, subnet->mapValue()) {
ParserPtr parser(createSubnet6ConfigParser(param.first));
// The actual type of the parser is unknown here. We have to discover
/// @throw isc::dhcp::Dhcp6ConfigError if subnet configuration parsing failed.
void createSubnet() {
- using namespace isc::dhcp;
-
// Find a subnet string.
StringStorage::const_iterator it = string_values_.find("subnet");
if (it == string_values_.end()) {
string subnet_txt = it->second;
boost::erase_all(subnet_txt, " ");
boost::erase_all(subnet_txt, "\t");
- // Get the address portion (without length).
+ // The subnet format is prefix/len. We are going to extract
+ // the prefix portion of a subnet string to create IOAddress
+ // object from it. IOAddress will be passed to the Subnet's
+ // constructor later on. In order to extract the prefix we
+ // need to get all characters preceding "/".
size_t pos = subnet_txt.find("/");
if (pos == string::npos) {
isc_throw(Dhcp6ConfigError,
// Get all 'time' parameters using inheritance.
// If the subnet-specific value is defined then use it, else
- // use the global value.
+ // use the global value. The global value must always be
+ // present. If it is not, it is an internal error and exception
+ // is thrown.
Triplet<uint32_t> t1 = getParam("renew-timer");
Triplet<uint32_t> t2 = getParam("rebind-timer");
Triplet<uint32_t> pref = getParam("preferred-lifetime");
DhcpConfigParser* createSubnet6ConfigParser(const std::string& config_id) {
FactoryMap factories;
- factories["preferred-lifetime"] = Uint32Parser::Factory;
- factories["valid-lifetime"] = Uint32Parser::Factory;
- factories["renew-timer"] = Uint32Parser::Factory;
- factories["rebind-timer"] = Uint32Parser::Factory;
- factories["subnet"] = StringParser::Factory;
- factories["pool"] = PoolParser::Factory;
- factories["option-data"] = OptionDataListParser::Factory;
+ factories["preferred-lifetime"] = Uint32Parser::factory;
+ factories["valid-lifetime"] = Uint32Parser::factory;
+ factories["renew-timer"] = Uint32Parser::factory;
+ factories["rebind-timer"] = Uint32Parser::factory;
+ factories["subnet"] = StringParser::factory;
+ factories["pool"] = PoolParser::factory;
+ factories["option-data"] = OptionDataListParser::factory;
FactoryMap::iterator f = factories.find(config_id);
if (f == factories.end()) {
/// @brief Returns Subnet6ListConfigParser object
/// @param param_name name of the parameter
/// @return Subnets6ListConfigParser object
- static DhcpConfigParser* Factory(const std::string& param_name) {
+ static DhcpConfigParser* factory(const std::string& param_name) {
return (new Subnets6ListConfigParser(param_name));
}
DhcpConfigParser* createGlobalDhcpConfigParser(const std::string& config_id) {
FactoryMap factories;
- factories["preferred-lifetime"] = Uint32Parser::Factory;
- factories["valid-lifetime"] = Uint32Parser::Factory;
- factories["renew-timer"] = Uint32Parser::Factory;
- factories["rebind-timer"] = Uint32Parser::Factory;
- factories["interface"] = InterfaceListConfigParser::Factory;
- factories["subnet6"] = Subnets6ListConfigParser::Factory;
- factories["option-data"] = OptionDataListParser::Factory;
- factories["version"] = StringParser::Factory;
+ factories["preferred-lifetime"] = Uint32Parser::factory;
+ factories["valid-lifetime"] = Uint32Parser::factory;
+ factories["renew-timer"] = Uint32Parser::factory;
+ factories["rebind-timer"] = Uint32Parser::factory;
+ factories["interface"] = InterfaceListConfigParser::factory;
+ factories["subnet6"] = Subnets6ListConfigParser::factory;
+ factories["option-data"] = OptionDataListParser::factory;
+ factories["version"] = StringParser::factory;
FactoryMap::iterator f = factories.find(config_id);
if (f == factories.end()) {
ParserCollection dependent_parsers;
// The subnet parsers implement data inheritance by directly
- // accesing global storages. For this reason the global data
+ // accessing global storages. For this reason the global data
// parsers must store the parsed data into global storages
- // immediatelly. This may cause data inconsistency if the
- // parsing operation fails after the global storage have been
- // already modified. We need to preserve the original global
- // data here so as we can rollback changes when an error occurs.
+ // immediately. This may cause data inconsistency if the
+ // parsing operation fails after the global storage has been
+ // modified. We need to preserve the original global data here
+ // so as we can rollback changes when an error occurs.
Uint32Storage uint32_local(uint32_defaults);
StringStorage string_local(string_defaults);
OptionStorage option_local(option_defaults);
// Iterate over all independent parsers first (all but subnet6)
// and try to parse the data.
BOOST_FOREACH(ConfigPair config_pair, config_set->mapValue()) {
- ParserPtr parser(createGlobalDhcpConfigParser(config_pair.first));
if (config_pair.first != "subnet6") {
+ ParserPtr parser(createGlobalDhcpConfigParser(config_pair.first));
independent_parsers.push_back(parser);
parser->build(config_pair.second);
// The commit operation here may modify the global storage
// Process dependent configuration data.
BOOST_FOREACH(ConfigPair config_pair, config_set->mapValue()) {
- ParserPtr parser(createGlobalDhcpConfigParser(config_pair.first));
if (config_pair.first == "subnet6") {
+ ParserPtr parser(createGlobalDhcpConfigParser(config_pair.first));
dependent_parsers.push_back(parser);
parser->build(config_pair.second);
}