2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 14:05:33 +00:00

[5073a] Addressed review comments

This commit is contained in:
Francis Dupont
2017-09-25 15:27:54 +02:00
parent 9ebab3b1e4
commit 5615b95f58
12 changed files with 56 additions and 32 deletions

View File

@@ -55,7 +55,7 @@
// In this particular class, we want to set specific values // In this particular class, we want to set specific values
// of certain DHCPv4 fields. If the incoming packet matches the // of certain DHCPv4 fields. If the incoming packet matches the
// test, those fields will be set in outgoing responses. // test, those fields will be set in outgoing responses.
// The option 43 is defined to encapsulate suboption inf the aastra space. // The option 43 is defined to encapsulate suboption in the aastra space.
{ {
"name": "VoIP", "name": "VoIP",
"test": "substring(option[60].hex,0,6) == 'Aastra'", "test": "substring(option[60].hex,0,6) == 'Aastra'",

View File

@@ -1528,9 +1528,9 @@ It is merely echoed by the server
They can be defined at the global scope or at client class local They can be defined at the global scope or at client class local
scope: this allows to use option definitions depending on context scope: this allows to use option definitions depending on context
and to set option data accordingly. and to set option data accordingly.
As the Vendor Specific Information option (code 43) can carry As the Vendor Specific Information option (code 43) has vendor
in a not compatible way a raw binary value or sub-options this specific format, i.e. can carry either raw binary value or
mechanism is available for this option too. sub-options, this mechanism is available for this option too.
</para> </para>
<para> <para>
The definition used to decode a VSI option is: The definition used to decode a VSI option is:
@@ -1637,6 +1637,11 @@ It is merely echoed by the server
... ...
}</screen> }</screen>
</para> </para>
<para>
Another possibility adde din Kea 1.3 is to redefine the option,
see <xref linkend="dhcp4-private-opts"/>.
</para>
</section> </section>
<section id="dhcp4-option-spaces"> <section id="dhcp4-option-spaces">

View File

@@ -171,7 +171,7 @@ Private (codes 224-254) and VSI (code 43) options are not decoded
by @c LibDHCP::unpackOptions4 but by @ref isc::dhcp::Dhcpv4Srv::deferredUnpack by @c LibDHCP::unpackOptions4 but by @ref isc::dhcp::Dhcpv4Srv::deferredUnpack
function after classification. To make this function to perform or not function after classification. To make this function to perform or not
deferred processing the simplest is to add or not the option code deferred processing the simplest is to add or not the option code
to the @ref isc::dhcp::Pkt4::deferredOptions list. to the @ref isc::dhcp::Pkt4::getDeferredOptions list.
@section dhcpv4DDNSIntegration DHCPv4 Server Support for the Dynamic DNS Updates @section dhcpv4DDNSIntegration DHCPv4 Server Support for the Dynamic DNS Updates
The DHCPv4 server supports processing of the DHCPv4 Client FQDN option (RFC4702) The DHCPv4 server supports processing of the DHCPv4 Client FQDN option (RFC4702)

View File

@@ -2827,7 +2827,7 @@ void
Dhcpv4Srv::deferredUnpack(Pkt4Ptr& query) Dhcpv4Srv::deferredUnpack(Pkt4Ptr& query)
{ {
// Iterate on the list of deferred option codes // Iterate on the list of deferred option codes
BOOST_FOREACH(const uint16_t& code, query->deferredOptions()) { BOOST_FOREACH(const uint16_t& code, query->getDeferredOptions()) {
OptionDefinitionPtr def; OptionDefinitionPtr def;
// Iterate on client classes // Iterate on client classes
const ClientClasses& classes = query->getClasses(); const ClientClasses& classes = query->getClasses();
@@ -2869,12 +2869,12 @@ Dhcpv4Srv::deferredUnpack(Pkt4Ptr& query)
// Get the existing option for its content and remove all // Get the existing option for its content and remove all
OptionPtr opt = query->getOption(code); OptionPtr opt = query->getOption(code);
if (!opt) { if (!opt) {
/* should not happen but do not crash anyway */ // should not happen but do not crash anyway
continue; continue;
} }
const OptionBuffer buf = opt->getData(); const OptionBuffer buf = opt->getData();
while (query->delOption(code)) { while (query->delOption(code)) {
/* continue */ // continue
} }
// Unpack the option and add it // Unpack the option and add it
opt = def->optionFactory(Option::V4, code, buf.cbegin(), buf.cend()); opt = def->optionFactory(Option::V4, code, buf.cbegin(), buf.cend());

View File

@@ -808,7 +808,10 @@ protected:
/// @note Options 43 and 224-254 are processed after classification. /// @note Options 43 and 224-254 are processed after classification.
/// If a class configures a definition it is applied, if none /// If a class configures a definition it is applied, if none
/// the global (user) definition is applied. For option 43 /// the global (user) definition is applied. For option 43
/// a last resort definition (same than for previous Kea) is used. /// a last resort definition (same definition as used in previous Kea
/// versions) is applied when none is found.
///
/// @param query Pointer to the client message.
void deferredUnpack(Pkt4Ptr& query); void deferredUnpack(Pkt4Ptr& query);
/// @brief Allocation Engine. /// @brief Allocation Engine.

View File

@@ -2300,7 +2300,9 @@ TEST_F(Dhcpv4SrvTest, option43BadRaw) {
NakedDhcpv4Srv srv(0); NakedDhcpv4Srv srv(0);
// The vendor-encapsulated-options has an incompatible data // The vendor-encapsulated-options has an incompatible data
// so won't have the expected content. // so won't have the expected content but processing of truncated
// (suboption length > available length) suboptions does not raise
// an exception.
string config = "{ \"interfaces-config\": {" string config = "{ \"interfaces-config\": {"
" \"interfaces\": [ \"*\" ] }, " " \"interfaces\": [ \"*\" ] }, "
"\"rebind-timer\": 2000, " "\"rebind-timer\": 2000, "
@@ -2343,7 +2345,7 @@ TEST_F(Dhcpv4SrvTest, option43BadRaw) {
buf.push_back(0x02); buf.push_back(0x02);
OptionPtr vopt(new Option(Option::V4, DHO_VENDOR_ENCAPSULATED_OPTIONS, buf)); OptionPtr vopt(new Option(Option::V4, DHO_VENDOR_ENCAPSULATED_OPTIONS, buf));
query->addOption(vopt); query->addOption(vopt);
query->deferredOptions().push_back(DHO_VENDOR_ENCAPSULATED_OPTIONS); query->getDeferredOptions().push_back(DHO_VENDOR_ENCAPSULATED_OPTIONS);
// Create and add a PRL option to the query // Create and add a PRL option to the query
OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4, OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
@@ -2386,7 +2388,9 @@ TEST_F(Dhcpv4SrvTest, option43FailRaw) {
NakedDhcpv4Srv srv(0); NakedDhcpv4Srv srv(0);
// The vendor-encapsulated-options has an incompatible data // The vendor-encapsulated-options has an incompatible data
// so won't have the expected content. // so won't have the expected content. Here the processing
// of suboptions tries to unpack the uitn32 foo suboption and
// raises an exception.
string config = "{ \"interfaces-config\": {" string config = "{ \"interfaces-config\": {"
" \"interfaces\": [ \"*\" ] }, " " \"interfaces\": [ \"*\" ] }, "
"\"rebind-timer\": 2000, " "\"rebind-timer\": 2000, "
@@ -2436,7 +2440,7 @@ TEST_F(Dhcpv4SrvTest, option43FailRaw) {
buf.push_back(0x01); buf.push_back(0x01);
OptionPtr vopt(new Option(Option::V4, DHO_VENDOR_ENCAPSULATED_OPTIONS, buf)); OptionPtr vopt(new Option(Option::V4, DHO_VENDOR_ENCAPSULATED_OPTIONS, buf));
query->addOption(vopt); query->addOption(vopt);
query->deferredOptions().push_back(DHO_VENDOR_ENCAPSULATED_OPTIONS); query->getDeferredOptions().push_back(DHO_VENDOR_ENCAPSULATED_OPTIONS);
// Create and add a PRL option to the query // Create and add a PRL option to the query
OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4, OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
@@ -2505,7 +2509,7 @@ TEST_F(Dhcpv4SrvTest, option43RawGlobal) {
buf.push_back(0x03); buf.push_back(0x03);
OptionPtr vopt(new Option(Option::V4, DHO_VENDOR_ENCAPSULATED_OPTIONS, buf)); OptionPtr vopt(new Option(Option::V4, DHO_VENDOR_ENCAPSULATED_OPTIONS, buf));
query->addOption(vopt); query->addOption(vopt);
query->deferredOptions().push_back(DHO_VENDOR_ENCAPSULATED_OPTIONS); query->getDeferredOptions().push_back(DHO_VENDOR_ENCAPSULATED_OPTIONS);
// Create and add a PRL option to the query // Create and add a PRL option to the query
OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4, OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
@@ -2600,7 +2604,7 @@ TEST_F(Dhcpv4SrvTest, option43RawClass) {
buf.push_back(0x03); buf.push_back(0x03);
OptionPtr vopt(new Option(Option::V4, DHO_VENDOR_ENCAPSULATED_OPTIONS, buf)); OptionPtr vopt(new Option(Option::V4, DHO_VENDOR_ENCAPSULATED_OPTIONS, buf));
query->addOption(vopt); query->addOption(vopt);
query->deferredOptions().push_back(DHO_VENDOR_ENCAPSULATED_OPTIONS); query->getDeferredOptions().push_back(DHO_VENDOR_ENCAPSULATED_OPTIONS);
// Create and add a PRL option to the query // Create and add a PRL option to the query
OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4, OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
@@ -2705,7 +2709,7 @@ TEST_F(Dhcpv4SrvTest, option43Class) {
buf.push_back(0x21); buf.push_back(0x21);
OptionPtr vopt(new Option(Option::V4, DHO_VENDOR_ENCAPSULATED_OPTIONS, buf)); OptionPtr vopt(new Option(Option::V4, DHO_VENDOR_ENCAPSULATED_OPTIONS, buf));
query->addOption(vopt); query->addOption(vopt);
query->deferredOptions().push_back(DHO_VENDOR_ENCAPSULATED_OPTIONS); query->getDeferredOptions().push_back(DHO_VENDOR_ENCAPSULATED_OPTIONS);
// Create and add a vendor-class-identifier (code 60) // Create and add a vendor-class-identifier (code 60)
OptionStringPtr iopt(new OptionString(Option::V4, OptionStringPtr iopt(new OptionString(Option::V4,
@@ -2839,7 +2843,7 @@ TEST_F(Dhcpv4SrvTest, option43ClassPriority) {
buf.push_back(0x21); buf.push_back(0x21);
OptionPtr vopt(new Option(Option::V4, DHO_VENDOR_ENCAPSULATED_OPTIONS, buf)); OptionPtr vopt(new Option(Option::V4, DHO_VENDOR_ENCAPSULATED_OPTIONS, buf));
query->addOption(vopt); query->addOption(vopt);
query->deferredOptions().push_back(DHO_VENDOR_ENCAPSULATED_OPTIONS); query->getDeferredOptions().push_back(DHO_VENDOR_ENCAPSULATED_OPTIONS);
// Create and add a vendor-class-identifier (code 60) // Create and add a vendor-class-identifier (code 60)
OptionStringPtr iopt(new OptionString(Option::V4, OptionStringPtr iopt(new OptionString(Option::V4,
@@ -2979,7 +2983,7 @@ TEST_F(Dhcpv4SrvTest, option43Classes) {
buf.push_back(0x21); buf.push_back(0x21);
OptionPtr vopt(new Option(Option::V4, DHO_VENDOR_ENCAPSULATED_OPTIONS, buf)); OptionPtr vopt(new Option(Option::V4, DHO_VENDOR_ENCAPSULATED_OPTIONS, buf));
query->addOption(vopt); query->addOption(vopt);
query->deferredOptions().push_back(DHO_VENDOR_ENCAPSULATED_OPTIONS); query->getDeferredOptions().push_back(DHO_VENDOR_ENCAPSULATED_OPTIONS);
// Create and add a vendor-class-identifier (code 60) // Create and add a vendor-class-identifier (code 60)
OptionStringPtr iopt(new OptionString(Option::V4, OptionStringPtr iopt(new OptionString(Option::V4,
@@ -3086,7 +3090,7 @@ TEST_F(Dhcpv4SrvTest, privateOption) {
buf.push_back(0x01); buf.push_back(0x01);
OptionPtr opt1(new Option(Option::V4, 234, buf)); OptionPtr opt1(new Option(Option::V4, 234, buf));
query->addOption(opt1); query->addOption(opt1);
query->deferredOptions().push_back(234); query->getDeferredOptions().push_back(234);
// Create and add a private option with code 245 // Create and add a private option with code 245
buf.clear(); buf.clear();
@@ -3096,7 +3100,7 @@ TEST_F(Dhcpv4SrvTest, privateOption) {
buf.push_back(0x21); buf.push_back(0x21);
OptionPtr opt2(new Option(Option::V4, 245, buf)); OptionPtr opt2(new Option(Option::V4, 245, buf));
query->addOption(opt2); query->addOption(opt2);
query->deferredOptions().push_back(245); query->getDeferredOptions().push_back(245);
// Create and add a PRL option to the query // Create and add a PRL option to the query

View File

@@ -294,7 +294,7 @@ LibDHCP::getLastResortOptionDefs(const std::string& space) {
} }
bool bool
LibDHCP::deferOption(const std::string& space, const uint16_t code) { LibDHCP::shouldDeferOptionUnpack(const std::string& space, const uint16_t code) {
return ((space == DHCP4_OPTION_SPACE) && return ((space == DHCP4_OPTION_SPACE) &&
((code == DHO_VENDOR_ENCAPSULATED_OPTIONS) || ((code == DHO_VENDOR_ENCAPSULATED_OPTIONS) ||
((code >= 224) && (code <= 254)))); ((code >= 224) && (code <= 254))));
@@ -546,7 +546,7 @@ size_t LibDHCP::unpackOptions4(const OptionBuffer& buf,
} }
// Check if option unpacking must be deferred // Check if option unpacking must be deferred
if (deferOption(option_space, opt_type)) { if (shouldDeferOptionUnpack(option_space, opt_type)) {
num_defs = 0; num_defs = 0;
deferred.push_back(opt_type); deferred.push_back(opt_type);
} }

View File

@@ -144,11 +144,12 @@ public:
/// ///
/// DHCPv4 option 43 and 224-254 unpacking is done after classification. /// DHCPv4 option 43 and 224-254 unpacking is done after classification.
/// ///
/// @space Option space name. /// @param space Option space name.
/// @param code Option code. /// @param code Option code.
/// ///
/// @return True if option processing should be deferred. /// @return True if option processing should be deferred.
static bool deferOption(const std::string& space, const uint16_t code); static bool shouldDeferOptionUnpack(const std::string& space,
const uint16_t code);
/// @brief Factory function to create instance of option. /// @brief Factory function to create instance of option.
/// ///
@@ -381,10 +382,13 @@ private:
/// is incorrect. This is a programming error. /// is incorrect. This is a programming error.
static void initStdOptionDefs6(); static void initStdOptionDefs6();
/// Initialize last resort DHCPv4 option definitions.
static void initLastResortOptionDefs(); static void initLastResortOptionDefs();
/// Initialize DOCSIS DHCPv4 option definitions.
static void initVendorOptsDocsis4(); static void initVendorOptsDocsis4();
/// Initialize DOCSIS DHCPv6 option definitions.
static void initVendorOptsDocsis6(); static void initVendorOptsDocsis6();
/// Initialize private DHCPv6 option definitions. /// Initialize private DHCPv6 option definitions.

View File

@@ -364,8 +364,14 @@ public:
return (local_hwaddr_); return (local_hwaddr_);
} }
/// @brief Returns a reference to deferred option codes /// @brief Returns a reference to option codes which unpacking
std::list<uint16_t>& deferredOptions() { /// will be deferred.
///
/// @notes Only options 42 and 224-254 are subject of deferred
/// unpacking: when the packet unpacking is performed each time
/// such an option is found it is unpacked as an unknown option
/// and the code added in this list.
std::list<uint16_t>& getDeferredOptions() {
return (deferred_options_); return (deferred_options_);
} }

View File

@@ -216,7 +216,8 @@ const OptionDefParams STANDARD_V4_OPTION_DEFINITIONS[] = {
const int STANDARD_V4_OPTION_DEFINITIONS_SIZE = const int STANDARD_V4_OPTION_DEFINITIONS_SIZE =
sizeof(STANDARD_V4_OPTION_DEFINITIONS) / sizeof(STANDARD_V4_OPTION_DEFINITIONS[0]); sizeof(STANDARD_V4_OPTION_DEFINITIONS) / sizeof(STANDARD_V4_OPTION_DEFINITIONS[0]);
/// Last resort definitions (only option 43 for now). /// Last resort definitions (only option 43 for now, these definitions
/// are applied in deferred unpacking when none is found).
const OptionDefParams LAST_RESORT_V4_OPTION_DEFINITIONS[] = { const OptionDefParams LAST_RESORT_V4_OPTION_DEFINITIONS[] = {
{ "vendor-encapsulated-options", DHO_VENDOR_ENCAPSULATED_OPTIONS, { "vendor-encapsulated-options", DHO_VENDOR_ENCAPSULATED_OPTIONS,
OPT_EMPTY_TYPE, false, NO_RECORD_DEF, "vendor-encapsulated-options-space" } OPT_EMPTY_TYPE, false, NO_RECORD_DEF, "vendor-encapsulated-options-space" }

View File

@@ -1815,10 +1815,10 @@ TEST_F(LibDhcpTest, setRuntimeOptionDefs) {
// This test verifies the processing of option 43 // This test verifies the processing of option 43
TEST_F(LibDhcpTest, option43) { TEST_F(LibDhcpTest, option43) {
// Check deferOption() // Check shouldDeferOptionUnpack()
EXPECT_TRUE(LibDHCP::deferOption(DHCP4_OPTION_SPACE, 43)); EXPECT_TRUE(LibDHCP::shouldDeferOptionUnpack(DHCP4_OPTION_SPACE, 43));
EXPECT_FALSE(LibDHCP::deferOption(DHCP4_OPTION_SPACE, 44)); EXPECT_FALSE(LibDHCP::shouldDeferOptionUnpack(DHCP4_OPTION_SPACE, 44));
EXPECT_FALSE(LibDHCP::deferOption(DHCP6_OPTION_SPACE, 43)); EXPECT_FALSE(LibDHCP::shouldDeferOptionUnpack(DHCP6_OPTION_SPACE, 43));
// Check last resort // Check last resort
OptionDefinitionPtr def; OptionDefinitionPtr def;

View File

@@ -101,7 +101,8 @@ ClientClassDefParser::parse(ClientClassDictionaryPtr& class_dictionary,
def = parser.parse(option_def); def = parser.parse(option_def);
// Verify if the defition is for an option which are // Verify if the defition is for an option which are
// in a deferred processing list. // in a deferred processing list.
if (!LibDHCP::deferOption(def.second, def.first->getCode())) { if (!LibDHCP::shouldDeferOptionUnpack(def.second,
def.first->getCode())) {
isc_throw(DhcpConfigError, isc_throw(DhcpConfigError,
"Not allowed option definition for code '" "Not allowed option definition for code '"
<< def.first->getCode() << "' in space '" << def.first->getCode() << "' in space '"