CfgMgr::instance().getStagingCfg()->setConfigControlInfo(config_ctl_info);
}
+ ConstElementPtr compatibility = mutable_cfg->get("compatibility");
+ if (compatibility) {
+ for (auto kv : compatibility->mapValue()) {
+ if (kv.first == "lenient-option-parsing") {
+ CfgMgr::instance().getStagingCfg()->setLenientOptionParsing(
+ kv.second->boolValue());
+ }
+ }
+ }
+
// Make parsers grouping.
ConfigPair config_pair;
const std::map<std::string, ConstElementPtr>& values_map =
parser.parse(srv_config, rsoo_list);
}
+ ConstElementPtr compatibility = mutable_cfg->get("compatibility");
+ if (compatibility) {
+ for (auto kv : compatibility->mapValue()) {
+ if (kv.first == "lenient-option-parsing") {
+ CfgMgr::instance().getStagingCfg()->setLenientOptionParsing(
+ kv.second->boolValue());
+ }
+ }
+ }
+
// Make parsers grouping.
ConfigPair config_pair;
const std::map<std::string, ConstElementPtr>& values_map =
#ifndef OPAQUE_DATA_TUPLE_H
#define OPAQUE_DATA_TUPLE_H
+#include <dhcp/option.h>
#include <util/buffer.h>
#include <util/io_utilities.h>
+
#include <iostream>
#include <iterator>
#include <string>
/// @param end Iterator pointing to the end of the buffer holding wire data.
/// @tparam InputIterator Type of the iterators passed to this function.
/// @throw It may throw an exception if the @c unpack throws.
- template<typename InputIterator>
- OpaqueDataTuple(LengthFieldType length_field_type, InputIterator begin,
+ template <typename InputIterator>
+ OpaqueDataTuple(LengthFieldType length_field_type,
+ InputIterator begin,
InputIterator end)
: length_field_type_(length_field_type) {
unpack(begin, end);
/// @tparam InputIterator Type of the iterators passed to this function.
template<typename InputIterator>
void unpack(InputIterator begin, InputIterator end) {
- Buffer buf(begin, end);
// The buffer must at least hold the size of the data.
if (std::distance(begin, end) < getDataFieldSize()) {
isc_throw(OpaqueDataTupleError,
// Now that we have the expected data size, let's check that the
// reminder of the buffer is long enough.
begin += getDataFieldSize();
+ // Attempt to parse as a length-value pair.
if (std::distance(begin, end) < len) {
- isc_throw(OpaqueDataTupleError,
- "unable to parse the opaque data tuple, the buffer"
- " length is " << std::distance(begin, end)
- << ", but the length of the tuple in the length field"
- " is " << len);
+ if (Option::lenient_parsing_) {
+ // Fallback to parsing the rest of the option as a single value.
+ len = std::distance(begin, end);
+ } else {
+ isc_throw(OpaqueDataTupleError,
+ "unable to parse the opaque data tuple, "
+ "the buffer length is " << std::distance(begin, end)
+ << ", but the tuple length is " << len);
+ }
}
// The buffer length is long enough to read the desired amount of data.
assign(begin, len);
/// @brief Buffer which holds the opaque tuple data.
Buffer data_;
+
/// @brief Holds a type of tuple size field (1 byte long or 2 bytes long).
LengthFieldType length_field_type_;
};
}
+bool Option::lenient_parsing_;
+
} // end of isc::dhcp namespace
} // end of isc namespace
/// @return true if options are equal, false otherwise.
virtual bool equals(const Option& other) const;
+ /// @brief Governs whether options should be parsed less strictly.
+ static bool lenient_parsing_;
+
protected:
/// @brief Copies this option and returns a pointer to the copy.
void
CfgMgr::commit() {
-
-
ensureCurrentAllocated();
// First we need to remove statistics. The new configuration can have fewer
// Now we need to set the statistics back.
configuration_->updateStatistics();
+
+ configuration_->injectIntoDependencies();
}
void
decline_timer_(0), echo_v4_client_id_(true), dhcp4o6_port_(0),
d2_client_config_(new D2ClientConfig()),
configured_globals_(Element::createMap()),
- cfg_consist_(new CfgConsistency()) {
+ cfg_consist_(new CfgConsistency()),
+ lenient_option_parsing_(false) {
}
SrvConfig::SrvConfig(const uint32_t sequence)
getCfgDbAccess()->setIPReservationsUnique(unique);
}
+void
+SrvConfig::injectIntoDependencies() const {
+ Option::lenient_parsing_ = lenient_option_parsing_;
+}
+
bool
DdnsParams::getEnableUpdates() const {
if (!subnet_) {
/// @return a pointer to unparsed configuration
virtual isc::data::ElementPtr toElement() const;
+ /// @brief Set lenient option parsing compatibility flag.
+ ///
+ /// @param value the boolean value to be set when configuring lenient option
+ /// parsing
+ void setLenientOptionParsing(bool const value) {
+ lenient_option_parsing_ = value;
+ }
+
+ /// @brief Get lenient option parsing compatibility flag.
+ ///
+ /// @return the configured value for lenient option parsing
+ bool getLenientOptionParsing() const {
+ return lenient_option_parsing_;
+ }
+
+ /// @brief Convenience method to inject configuration parameters into
+ /// internal libraries that don't have access to the server's current
+ /// configuration
+ ///
+ /// Happen on configuration commit.
+ void injectIntoDependencies() const;
+
private:
/// @brief Merges the DHCPv4 configuration specified as a parameter into
/// @brief Pointer to the configuration consistency settings
CfgConsistencyPtr cfg_consist_;
+
+ /// @brief Compatibility flags
+ /// @{
+ bool lenient_option_parsing_;
+ /// @}
};
/// @name Pointers to the @c SrvConfig object.