diff --git a/src/lib/dhcp/option4_dnr.cc b/src/lib/dhcp/option4_dnr.cc index a848d92d92..f3985324c6 100644 --- a/src/lib/dhcp/option4_dnr.cc +++ b/src/lib/dhcp/option4_dnr.cc @@ -48,42 +48,48 @@ Option4Dnr::pack(OutputBuffer& buf, bool check) const { void Option4Dnr::unpack(OptionBufferConstIter begin, OptionBufferConstIter end) { - setData(begin, end); - while (begin != end) { - DnrInstance dnr_instance(V4); - if (std::distance(begin, end) < dnr_instance.getMinimalLength()) { - isc_throw(OutOfRange, dnr_instance.getLogPrefix() - << "DNR instance data truncated to size " - << std::distance(begin, end)); - } + if (convenient_notation_) { + // parse convenient notation + std::string config_txt = std::string(begin, end); + parseConfigData(config_txt); + } else { + setData(begin, end); + while (begin != end) { + DnrInstance dnr_instance(V4); + if (std::distance(begin, end) < dnr_instance.getMinimalLength()) { + isc_throw(OutOfRange, dnr_instance.getLogPrefix() + << "DNR instance data truncated to size " + << std::distance(begin, end)); + } - // Unpack DnrInstanceDataLength. - dnr_instance.unpackDnrInstanceDataLength(begin, end); + // Unpack DnrInstanceDataLength. + dnr_instance.unpackDnrInstanceDataLength(begin, end); - const OptionBufferConstIter dnr_instance_end = begin + - dnr_instance.getDnrInstanceDataLength(); + const OptionBufferConstIter dnr_instance_end = begin + + dnr_instance.getDnrInstanceDataLength(); - // Unpack Service priority. - dnr_instance.unpackServicePriority(begin); + // Unpack Service priority. + dnr_instance.unpackServicePriority(begin); - // Unpack ADN len + ADN. - dnr_instance.unpackAdn(begin, dnr_instance_end); + // Unpack ADN len + ADN. + dnr_instance.unpackAdn(begin, dnr_instance_end); + + if (begin == dnr_instance_end) { + // ADN only mode, other fields are not included. + addDnrInstance(dnr_instance); + continue; + } + + dnr_instance.setAdnOnlyMode(false); + + // Unpack Addr Len + IPv4 Address(es). + dnr_instance.unpackAddresses(begin, dnr_instance_end); + + // SvcParams (variable length) field is last. + dnr_instance.unpackSvcParams(begin, dnr_instance_end); - if (begin == dnr_instance_end) { - // ADN only mode, other fields are not included. addDnrInstance(dnr_instance); - continue; } - - dnr_instance.setAdnOnlyMode(false); - - // Unpack Addr Len + IPv4 Address(es). - dnr_instance.unpackAddresses(begin, dnr_instance_end); - - // SvcParams (variable length) field is last. - dnr_instance.unpackSvcParams(begin, dnr_instance_end); - - addDnrInstance(dnr_instance); } } @@ -119,6 +125,11 @@ Option4Dnr::addDnrInstance(DnrInstance& dnr_instance) { dnr_instances_.push_back(dnr_instance); } +void +Option4Dnr::parseConfigData(const std::string& config_txt) { + // TBD +} + const std::unordered_set DnrInstance::FORBIDDEN_SVC_PARAMS = {"ipv4hint", "ipv6hint"}; DnrInstance::DnrInstance(Option::Universe universe) diff --git a/src/lib/dhcp/option4_dnr.h b/src/lib/dhcp/option4_dnr.h index 221a5ee8cc..fee4c60a8a 100644 --- a/src/lib/dhcp/option4_dnr.h +++ b/src/lib/dhcp/option4_dnr.h @@ -546,6 +546,17 @@ private: /// @brief Flag stating whether the %Option was constructed with a convenient notation string, /// that needs custom parsing, or binary data. bool convenient_notation_; + + /// @brief Parses a convenient notation of the option data, which may be used in config. + /// + /// As an alternative to the binary format, + /// we provide convenience option definition as a string in format: + /// TBD + /// + /// @param config_txt convenient notation of the option data received as string + /// + /// @throw BadValue Thrown in case parser found wrong format of received string. + void parseConfigData(const std::string& config_txt); }; /// A pointer to the @c OptionDnr4 object. diff --git a/src/lib/dhcp/option6_dnr.cc b/src/lib/dhcp/option6_dnr.cc index 389c3adeb2..e4daefce53 100644 --- a/src/lib/dhcp/option6_dnr.cc +++ b/src/lib/dhcp/option6_dnr.cc @@ -55,31 +55,37 @@ Option6Dnr::packAddresses(util::OutputBuffer& buf) const { void Option6Dnr::unpack(OptionBufferConstIter begin, OptionBufferConstIter end) { - if (std::distance(begin, end) < getMinimalLength()) { - isc_throw(OutOfRange, getLogPrefix() - << "data truncated to size " << std::distance(begin, end)); + if (convenient_notation_) { + // parse convenient notation + std::string config_txt = std::string(begin, end); + parseConfigData(config_txt); + } else { + if (std::distance(begin, end) < getMinimalLength()) { + isc_throw(OutOfRange, getLogPrefix() + << "data truncated to size " << std::distance(begin, end)); + } + + setData(begin, end); + + // First two octets of Option data is Service Priority - this is mandatory field. + unpackServicePriority(begin); + + // Next come two octets of ADN Length plus the ADN data itself (variable length). + // This is Opaque Data Tuple so let's use this class to retrieve the ADN data. + unpackAdn(begin, end); + + if (begin == end) { + // ADN only mode, other fields are not included. + return; + } + + adn_only_mode_ = false; + + unpackAddresses(begin, end); + + // SvcParams (variable length) field is last. + unpackSvcParams(begin, end); } - - setData(begin, end); - - // First two octets of Option data is Service Priority - this is mandatory field. - unpackServicePriority(begin); - - // Next come two octets of ADN Length plus the ADN data itself (variable length). - // This is Opaque Data Tuple so let's use this class to retrieve the ADN data. - unpackAdn(begin, end); - - if (begin == end) { - // ADN only mode, other fields are not included. - return; - } - - adn_only_mode_ = false; - - unpackAddresses(begin, end); - - // SvcParams (variable length) field is last. - unpackSvcParams(begin, end); } std::string @@ -143,5 +149,10 @@ Option6Dnr::unpackAddresses(OptionBufferConstIter& begin, OptionBufferConstIter } } +void +Option6Dnr::parseConfigData(const std::string& config_txt){ + // TBD +} + } // namespace dhcp } // namespace isc diff --git a/src/lib/dhcp/option6_dnr.h b/src/lib/dhcp/option6_dnr.h index f7fbeaa4d4..4a453f0524 100644 --- a/src/lib/dhcp/option6_dnr.h +++ b/src/lib/dhcp/option6_dnr.h @@ -146,6 +146,17 @@ private: /// @brief Flag stating whether the %Option was constructed with a convenient notation string, /// that needs custom parsing, or binary data. bool convenient_notation_; + + /// @brief Parses a convenient notation of the option data, which may be used in config. + /// + /// As an alternative to the binary format, + /// we provide convenience option definition as a string in format: + /// TBD + /// + /// @param config_txt convenient notation of the option data received as string + /// + /// @throw BadValue Thrown in case parser found wrong format of received string. + void parseConfigData(const std::string& config_txt); }; /// A pointer to the @c Option6Dnr object.