+1838. [bug] fdupont
+ The DHCPv6 sent multiple instances of an option or a
+ sub-option when it seems to be requested more than once
+ directly by the client or using the always-send flag.
+ (Gitlab #1449)
+
1837. [doc] cstrotm
Several Kea ARM corrections.
(Gitlab #1514)
bool added = false;
for (std::vector<uint8_t>::const_iterator code = requested_opts.begin();
code != requested_opts.end(); ++code) {
- if (!vendor_rsp->getOption(*code)) {
+ if (!vendor_rsp->getOption(*code)) {
for (CfgOptionList::const_iterator copts = co_list.begin();
copts != co_list.end(); ++copts) {
OptionDescriptor desc = (*copts)->get(vendor_id, *code);
}
}
- BOOST_FOREACH(uint16_t opt, requested_opts) {
- // Iterate on the configured option list
- for (CfgOptionList::const_iterator copts = co_list.begin();
- copts != co_list.end(); ++copts) {
- OptionDescriptor desc = (*copts)->get(DHCP6_OPTION_SPACE, opt);
- // Got it: add it and jump to the outer loop
- if (desc.option_) {
- answer->addOption(desc.option_);
- break;
+ for (uint16_t opt : requested_opts) {
+ // Add nothing when it is already there.
+ if (!answer->getOption(opt)) {
+ // Iterate on the configured option list
+ for (CfgOptionList::const_iterator copts = co_list.begin();
+ copts != co_list.end(); ++copts) {
+ OptionDescriptor desc = (*copts)->get(DHCP6_OPTION_SPACE, opt);
+ // Got it: add it and jump to the outer loop
+ if (desc.option_) {
+ answer->addOption(desc.option_);
+ break;
+ }
}
}
}
// Get the list of options that client requested.
bool added = false;
- BOOST_FOREACH(uint16_t opt, requested_opts) {
+ for (uint16_t opt : requested_opts) {
for (CfgOptionList::const_iterator copts = co_list.begin();
copts != co_list.end(); ++copts) {
- OptionDescriptor desc = (*copts)->get(vendor_id, opt);
- if (desc.option_) {
- vendor_rsp->addOption(desc.option_);
- added = true;
- break;
+ if (!vendor_rsp->getOption(opt)) {
+ OptionDescriptor desc = (*copts)->get(vendor_id, opt);
+ if (desc.option_) {
+ vendor_rsp->addOption(desc.option_);
+ added = true;
+ break;
+ }
}
}
}
ASSERT_TRUE(response->getOption(D6O_NAME_SERVERS));
// and still no sntp-servers
ASSERT_FALSE(response->getOption(D6O_SNTP_SERVERS));
+
+ // Reset ORO adding subscriber-id
+ sol->delOption(D6O_ORO);
+ OptionUint16ArrayPtr oro2(new OptionUint16Array(Option::V6, D6O_ORO));
+ ASSERT_TRUE(oro2);
+ oro2->addValue(D6O_SUBSCRIBER_ID);
+ sol->addOption(oro2);
+
+ // Let the server process it again.
+ AllocEngine::ClientContext6 ctx3;
+ srv_.initContext(sol, ctx3, drop);
+ ASSERT_FALSE(drop);
+ response = srv_.processSolicit(ctx3);
+
+ // The subscriber-id option should be present but only once despite
+ // it is both requested and has always-send.
+ const OptionCollection& sifs = response->getOptions(D6O_SUBSCRIBER_ID);
+ ASSERT_EQ(1, sifs.size());
+ // But no dns-servers
+ ASSERT_FALSE(response->getOption(D6O_NAME_SERVERS));
+ // Nor a sntp-servers
+ ASSERT_FALSE(response->getOption(D6O_SNTP_SERVERS));
}
// Checks if server is able to handle a relayed traffic from DOCSIS3.0 modems
OptionStringPtr config_file = boost::dynamic_pointer_cast<OptionString>(docsis33);
ASSERT_TRUE(config_file);
EXPECT_EQ("normal_erouter_v6.cm", config_file->getValue());
+
+ // Let's add a vendor-option (vendor-id=4491) with a single sub-option.
+ // That suboption has code 1 and is a docsis ORO option.
+ sol->delOption(D6O_VENDOR_OPTS);
+ boost::shared_ptr<OptionUint16Array> vendor_oro(new OptionUint16Array(Option::V6,
+ DOCSIS3_V6_ORO));
+ vendor_oro->addValue(DOCSIS3_V6_CONFIG_FILE); // Request option 33
+ OptionPtr vendor2(new OptionVendor(Option::V6, 4491));
+ vendor2->addOption(vendor_oro);
+ sol->addOption(vendor2);
+
+ // Need to process SOLICIT again after requesting new option.
+ AllocEngine::ClientContext6 ctx2;
+ srv_.initContext(sol, ctx2, drop);
+ ASSERT_FALSE(drop);
+ adv = srv_.processSolicit(ctx2);
+ ASSERT_TRUE(adv);
+
+ // Check if there is vendor option response
+ tmp = adv->getOption(D6O_VENDOR_OPTS);
+ ASSERT_TRUE(tmp);
+
+ // The response should be OptionVendor object
+ vendor_resp = boost::dynamic_pointer_cast<OptionVendor>(tmp);
+ ASSERT_TRUE(vendor_resp);
+
+ // There should be only one suboption despite config-file is both
+ // requested and has the always-send flag.
+ const OptionCollection& opts = vendor_resp->getOptions();
+ ASSERT_EQ(1, opts.size());
}
// Test checks whether it is possible to use option definitions defined in