}
}
+\"extended-info-checks\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::SANITY_CHECKS:
+ return isc::dhcp::Dhcp4Parser::make_EXTENDED_INFO_CHECKS(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("extended-info-checks", driver.loc_);
+ }
+}
+
\"dhcp-socket-type\" {
switch(driver.ctx_) {
case isc::dhcp::Parser4Context::INTERFACES_CONFIG:
SANITY_CHECKS "sanity-checks"
LEASE_CHECKS "lease-checks"
+ EXTENDED_INFO_CHECKS "extended-info-checks"
ECHO_CLIENT_ID "echo-client-id"
MATCH_CLIENT_ID "match-client-id"
}
;
-sanity_checks_param: lease_checks;
+sanity_checks_param: lease_checks
+ | extended_info_checks
+ ;
lease_checks: LEASE_CHECKS {
ctx.unique("lease-checks", ctx.loc2pos(@1));
}
}
+extended_info_checks: EXTENDED_INFO_CHECKS {
+ ctx.unique("extended-info-checks", ctx.loc2pos(@1));
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+
+ if ( (string($4) == "none") ||
+ (string($4) == "fix") ||
+ (string($4) == "strict") ||
+ (string($4) == "pedantic")) {
+ ElementPtr user(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("extended-info-checks", user);
+ ctx.leave();
+ } else {
+ error(@4, "Unsupported 'extended-info-checks value: " + string($4) +
+ ", supported values are: none, fix, strict, pedantic");
+ }
+}
+
hosts_database: HOSTS_DATABASE {
ctx.unique("hosts-database", ctx.loc2pos(@1));
ElementPtr i(new MapElement(ctx.loc2pos(@1)));
}
}
+\"extended-info-checks\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::SANITY_CHECKS:
+ return isc::dhcp::Dhcp6Parser::make_EXTENDED_INFO_CHECKS(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("extended-info-checks", driver.loc_);
+ }
+}
+
\"lease-database\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::DHCP6:
SANITY_CHECKS "sanity-checks"
LEASE_CHECKS "lease-checks"
+ EXTENDED_INFO_CHECKS "extended-info-checks"
CLIENT_CLASSES "client-classes"
REQUIRE_CLIENT_CLASSES "require-client-classes"
}
;
-sanity_checks_param: lease_checks;
+sanity_checks_param: lease_checks
+ | extended_info_checks
+ ;
lease_checks: LEASE_CHECKS {
ctx.unique("lease-checks", ctx.loc2pos(@1));
}
}
+extended_info_checks: EXTENDED_INFO_CHECKS {
+ ctx.unique("extended-info-checks", ctx.loc2pos(@1));
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+
+ if ( (string($4) == "none") ||
+ (string($4) == "fix") ||
+ (string($4) == "strict") ||
+ (string($4) == "pedantic")) {
+ ElementPtr user(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("extended-info-checks", user);
+ ctx.leave();
+ } else {
+ error(@4, "Unsupported 'extended-info-checks value: " + string($4) +
+ ", supported values are: none, fix, strict, pedantic");
+ }
+}
+
mac_sources: MAC_SOURCES {
ctx.unique("mac-sources", ctx.loc2pos(@1));
ElementPtr l(new ListElement(ctx.loc2pos(@1)));
-// Copyright (C) 2018-2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
ElementPtr m(new MapElement());
ElementPtr l(new StringElement(sanityCheckToText(getLeaseSanityCheck())));
m->set("lease-checks", l);
+ ElementPtr x(new StringElement(sanityCheckToText(getExtendedInfoSanityCheck())));
+ m->set("extended-info-checks", x);
return (m);
}
}
}
-};
-};
-
+std::string CfgConsistency::sanityCheckToText(ExtendedInfoSanity check_type) {
+ switch (check_type) {
+ case EXTENDED_INFO_CHECK_NONE:
+ return ("none");
+ case EXTENDED_INFO_CHECK_FIX:
+ return ("fix");
+ case EXTENDED_INFO_CHECK_STRICT:
+ return ("strict");
+ case EXTENDED_INFO_CHECK_PEDANTIC:
+ return ("pedantic");
+ default:
+ return ("unknown");
+ }
+}
+}
+}
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
LEASE_CHECK_DEL // Delete leases with invalid subnet-id.
};
+ /// @brief Values for extended info sanity checks done for leases.
+ enum ExtendedInfoSanity {
+ EXTENDED_INFO_CHECK_NONE, // Skip sanity checks.
+ EXTENDED_INFO_CHECK_FIX, // Fix extended info common inconsistencies.
+ EXTENDED_INFO_CHECK_STRICT, // Fix extended info inconsistencies which
+ // have an impact for Bulk Lease Query.
+ EXTENDED_INFO_CHECK_PEDANTIC // Fix all extended info inconsistencies.
+ };
+
/// @brief Constructor
CfgConsistency()
- : lease_sanity_check_(LEASE_CHECK_NONE) {
-
+ : lease_sanity_check_(LEASE_CHECK_NONE),
+ extended_info_sanity_check_(EXTENDED_INFO_CHECK_FIX) {
}
/// @brief Returns JSON representation
return (lease_sanity_check_);
}
- /// @brief Converts sanity check value to printable text
+ /// @brief Converts lease sanity check value to printable text.
///
/// @param check_type sanity mode to be converted
static std::string sanityCheckToText(LeaseSanity check_type);
+ /// @brief Sets specific sanity checks mode for extended info.
+ ///
+ /// @param l sanity checks mode
+ void setExtendedInfoSanityCheck(ExtendedInfoSanity l) {
+ extended_info_sanity_check_ = l;
+ }
+
+ /// @brief Returns specific sanity checks mode for extended info.
+ ///
+ /// @return sanity checks mode
+ ExtendedInfoSanity getExtendedInfoSanityCheck() const {
+ return (extended_info_sanity_check_);
+ }
+
+ /// @brief Converts extended info sanity check value to printable text.
+ ///
+ /// @param check_type sanity mode to be converted
+ static std::string sanityCheckToText(ExtendedInfoSanity check_type);
+
private:
- /// @brief sanity checks mode
+ /// @brief lease sanity checks mode.
LeaseSanity lease_sanity_check_;
+
+ /// @brief extended info sanity checks mode.
+ ExtendedInfoSanity extended_info_sanity_check_;
};
/// @brief Type used to for pointing to CfgConsistency structure
typedef boost::shared_ptr<CfgConsistency> CfgConsistencyPtr;
-}; // namespace isc::dhcp
-}; // namespace isc
+} // namespace isc::dhcp
+} // namespace isc
#endif /* CFG_CONSISTENCY_H */
// Try to decode sub-options.
string rai_hex = extended_info->stringValue();
- if ((rai_hex.size() < 3) || (rai_hex[0] != '0') || (rai_hex[1] != 'x')) {
- return (changed);
- }
try {
vector<uint8_t> rai_data;
- encode::decodeHex(rai_hex.substr(2), rai_data);
+ encode::decodeHex(rai_hex, rai_data);
OptionCustomPtr rai(new OptionCustom(*rai_def, Option::V4, rai_data));
if (!rai) {
return (changed);
return (changed);
}
string options_hex = options->stringValue();
- if ((options_hex.size() < 3) || (options_hex[0] != '0') ||
- (options_hex[1] != 'x')) {
- return (changed);
- }
try {
vector<uint8_t> options_data;
- encode::decodeHex(options_hex.substr(2), options_data);
+ encode::decodeHex(options_hex, options_data);
OptionCollection opts;
LibDHCP::unpackOptions6(options_data, DHCP6_OPTION_SPACE, opts);
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
isc_throw(DhcpConfigError, "sanity-checks is supposed to be a map");
}
- ConstElementPtr lease_checks = sanity_checks->get("lease-checks");
- if (lease_checks) {
- if (lease_checks->getType() != Element::string) {
+ // Subnet-id lease checker.
+ ConstElementPtr checks = sanity_checks->get("lease-checks");
+ if (checks) {
+ if (checks->getType() != Element::string) {
isc_throw(DhcpConfigError, "lease-checks must be a string");
}
- std::string lc = lease_checks->stringValue();
+ std::string lc = checks->stringValue();
CfgConsistency::LeaseSanity check;
if (lc == "none") {
check = CfgConsistency::LEASE_CHECK_NONE;
cfg.getConsistency()->setLeaseSanityCheck(check);
}
+ // Extended info lease checker.
+ checks = sanity_checks->get("extended-info-checks");
+ if (checks) {
+ if (checks->getType() != Element::string) {
+ isc_throw(DhcpConfigError, "extended-info-checks must be a string");
+ }
+ std::string exc = checks->stringValue();
+ CfgConsistency::ExtendedInfoSanity check;
+ if (exc == "none") {
+ check = CfgConsistency::EXTENDED_INFO_CHECK_NONE;
+ } else if (exc == "fix") {
+ check = CfgConsistency::EXTENDED_INFO_CHECK_FIX;
+ } else if (exc == "strict") {
+ check = CfgConsistency::EXTENDED_INFO_CHECK_STRICT;
+ } else if (exc == "pedantic") {
+ check = CfgConsistency::EXTENDED_INFO_CHECK_PEDANTIC;
+ } else {
+ isc_throw(DhcpConfigError,
+ "Unsupported extended-info-checks value: " << exc
+ << ", supported values are: none, fix, strict, pedantic");
+ }
+ cfg.getConsistency()->setExtendedInfoSanityCheck(check);
+ }
+
// Additional sanity check fields will come in later here.
}
-};
-};
+}
+}
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
void parse(SrvConfig& srv_cfg, const isc::data::ConstElementPtr& value);
};
-};
-};
+}
+}
#endif /* SANITY_CHECKS_PARSER_H */
-// Copyright (C) 2018-2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
default:
// Shouldn't get here but some compilers and analyzers
- // complain. We'll we treat it as NONE and return the
+ // complain. We'll we treat it as NONE and return the
// lease as-is.
break;
return (subnet->getID());
}
-};
-};
+}
+}
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
/// This class is expected to be used as a simple interface sanity checker for
/// various run-time and configuration elements. Currently is provides sanity
/// checking and correction for subnet-id parameter in leases.
+///
+/// @note: the extended info checker for leases is in the lease manager.
class SanityChecker {
- public:
+public:
/// @brief Sanity checks and possibly corrects an IPv4 lease
///
SubnetID findSubnetId(const LeaseType& lease, const SubnetsType& subnets);
};
-
-};
-};
-
+}
+}
#endif /* SANITY_CHECKER_H */
-// Copyright (C) 2018-2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
vector<uint8_t> clientid(1);
- time_t timestamp = time(NULL) - 86400 + random()%86400;
+ time_t timestamp = time(0) - 86400 + random()%86400;
// Return created lease.
return (Lease4Ptr(new Lease4(address, hwaddr,
void
parserCheck(SrvConfig& cfg, const string& txt, bool exp_throw,
- CfgConsistency::LeaseSanity exp_sanity) {
+ CfgConsistency::LeaseSanity exp_sanity,
+ CfgConsistency::ExtendedInfoSanity exp_sanity2) {
+ // Reset to defaults.
+ cfg.getConsistency()->setLeaseSanityCheck(CfgConsistency::LEASE_CHECK_NONE);
+ cfg.getConsistency()->setExtendedInfoSanityCheck(CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+
SanityChecksParser parser;
ElementPtr json;
EXPECT_NO_THROW(json = Element::fromJSON(txt));
if (exp_throw) {
- EXPECT_THROW(parser.parse(cfg, json), DhcpConfigError);
-
- return;
+ // Should throw DhcpConfigError.
+ try {
+ parser.parse(cfg, json);
+ ADD_FAILURE() << "should throw not did not throw";
+ return;
+ } catch (const DhcpConfigError&) {
+ return;
+ } catch (const exception& ex) {
+ ADD_FAILURE() << "throw another exception with " << ex.what();
+ }
+ } else {
+ // Should not throw.
+ try {
+ parser.parse(cfg, json);
+ } catch (const exception& ex) {
+ ADD_FAILURE() << "throw an exception with " << ex.what();
+ }
}
- // Should not throw.
- EXPECT_NO_THROW(parser.parse(cfg, json));
-
EXPECT_EQ(cfg.getConsistency()->getLeaseSanityCheck(), exp_sanity);
+ EXPECT_EQ(cfg.getConsistency()->getExtendedInfoSanityCheck(), exp_sanity2);
}
};
string bogus3 = "{ \"lease-checks\": true }";
string bogus4 = "{ \"lease-checks\": 42 }";
+ // These are valid and should be accepted.
+ string valid6 = "{ \"extended-info-checks\": \"none\" }";
+ string valid7 = "{ \"extended-info-checks\": \"fix\" }";
+ string valid8 = "{ \"extended-info-checks\": \"strict\" }";
+ string valid9 = "{ \"extended-info-checks\": \"pedantic\" }";
+ string valid10 = "{ \"lease-checks\": \"fix\",\n"
+ " \"extended-info-checks\": \"fix\" }";
+
+ string bogus5 = "{ \"extended-info-checks\": \"sanitize\" }";
+ string bogus6 = "{ \"extended-info-checks\": \"ignore\" }";
+ string bogus7 = "{ \"extended-info-checks\": true }";
+ string bogus8 = "{ \"extended-info-checks\": 42 }";
+
SrvConfig cfg;
- // The default should be to none.
+ // The lease default should be to none.
EXPECT_EQ(cfg.getConsistency()->getLeaseSanityCheck(),
CfgConsistency::LEASE_CHECK_NONE);
- parserCheck(cfg, valid1, false, CfgConsistency::LEASE_CHECK_NONE);
- parserCheck(cfg, valid2, false, CfgConsistency::LEASE_CHECK_WARN);
- parserCheck(cfg, valid3, false, CfgConsistency::LEASE_CHECK_FIX);
- parserCheck(cfg, valid4, false, CfgConsistency::LEASE_CHECK_FIX_DEL);
- parserCheck(cfg, valid5, false, CfgConsistency::LEASE_CHECK_DEL);
-
- parserCheck(cfg, bogus1, true, CfgConsistency::LEASE_CHECK_NONE);
- parserCheck(cfg, bogus2, true, CfgConsistency::LEASE_CHECK_NONE);
- parserCheck(cfg, bogus3, true, CfgConsistency::LEASE_CHECK_NONE);
- parserCheck(cfg, bogus4, true, CfgConsistency::LEASE_CHECK_NONE);
+ // The extended info default should be to fix.
+ EXPECT_EQ(cfg.getConsistency()->getExtendedInfoSanityCheck(),
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+
+ parserCheck(cfg, valid1, false, CfgConsistency::LEASE_CHECK_NONE,
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+ parserCheck(cfg, valid2, false, CfgConsistency::LEASE_CHECK_WARN,
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+ parserCheck(cfg, valid3, false, CfgConsistency::LEASE_CHECK_FIX,
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+ parserCheck(cfg, valid4, false, CfgConsistency::LEASE_CHECK_FIX_DEL,
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+ parserCheck(cfg, valid5, false, CfgConsistency::LEASE_CHECK_DEL,
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+
+ parserCheck(cfg, bogus1, true, CfgConsistency::LEASE_CHECK_NONE,
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+ parserCheck(cfg, bogus2, true, CfgConsistency::LEASE_CHECK_NONE,
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+ parserCheck(cfg, bogus3, true, CfgConsistency::LEASE_CHECK_NONE,
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+ parserCheck(cfg, bogus4, true, CfgConsistency::LEASE_CHECK_NONE,
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+
+ parserCheck(cfg, valid6, false, CfgConsistency::LEASE_CHECK_NONE,
+ CfgConsistency::EXTENDED_INFO_CHECK_NONE);
+ parserCheck(cfg, valid7, false, CfgConsistency::LEASE_CHECK_NONE,
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+ parserCheck(cfg, valid8, false, CfgConsistency::LEASE_CHECK_NONE,
+ CfgConsistency::EXTENDED_INFO_CHECK_STRICT);
+ parserCheck(cfg, valid9, false, CfgConsistency::LEASE_CHECK_NONE,
+ CfgConsistency::EXTENDED_INFO_CHECK_PEDANTIC);
+ parserCheck(cfg, valid10, false, CfgConsistency::LEASE_CHECK_FIX,
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+
+ parserCheck(cfg, bogus5, true, CfgConsistency::LEASE_CHECK_NONE,
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+ parserCheck(cfg, bogus6, true, CfgConsistency::LEASE_CHECK_NONE,
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+ parserCheck(cfg, bogus7, true, CfgConsistency::LEASE_CHECK_NONE,
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
+ parserCheck(cfg, bogus8, true, CfgConsistency::LEASE_CHECK_NONE,
+ CfgConsistency::EXTENDED_INFO_CHECK_FIX);
}
// Verify whether sanity checker works as expected (valid v4).
ASSERT_TRUE(lease);
EXPECT_EQ(subnet->getID(), lease->subnet_id_);
}
-