14 #include <boost/algorithm/string/split.hpp>
15 #include <boost/algorithm/string/classification.hpp>
16 #include <boost/make_shared.hpp>
27 OptionDescriptor::create(
const OptionPtr& opt,
bool persist,
28 const std::string& formatted_value,
30 return (boost::make_shared<OptionDescriptor>(opt, persist, formatted_value,
35 OptionDescriptor::create(
bool persist) {
36 return (boost::make_shared<OptionDescriptor>(persist));
41 return (boost::make_shared<OptionDescriptor>(desc));
49 option_->equals(other.
option_));
52 CfgOption::CfgOption() {
56 CfgOption::empty()
const {
57 return (options_.empty() && vendor_options_.empty());
62 return (options_.equals(other.options_) &&
63 vendor_options_.equals(other.vendor_options_));
67 CfgOption::add(
const OptionPtr& option,
const bool persistent,
68 const std::string& option_space,
74 add(desc, option_space);
82 }
else if (!OptionSpace::validateName(option_space)) {
84 << option_space <<
"'");
87 const uint32_t vendor_id = LibDHCP::optionSpaceToVendorId(option_space);
89 vendor_options_.addItem(desc, vendor_id);
91 options_.addItem(desc, option_space);
105 <<
" does not exist");
110 OptionContainerTypeIndex::const_iterator od_itr = idx.find(desc.
option_->getType());
111 if (od_itr == idx.end()) {
113 << option_space <<
":" << desc.
option_->getType()
114 <<
", it does not exist");
117 idx.replace(od_itr, desc);
121 std::list<std::string>
122 CfgOption::getVendorIdsSpaceNames()
const {
123 std::list<uint32_t> ids = getVendorIds();
124 std::list<std::string> names;
125 for (std::list<uint32_t>::const_iterator
id = ids.begin();
126 id != ids.end(); ++id) {
127 std::ostringstream s;
130 s <<
"vendor-" << *id;
131 names.push_back(s.str());
156 for (
auto space : getOptionSpaceNames()) {
157 for (
auto opt_desc : *(getAll(space))) {
158 if (createDescriptorOption(cfg_def, space, opt_desc)) {
160 replace(opt_desc,space);
171 "validateCreateOption: descriptor has no option instance");
175 uint16_t code = opt_desc.
option_->getType();
184 uint32_t vendor_id = LibDHCP::optionSpaceToVendorId(space);
186 def = LibDHCP::getVendorOptionDef(universe, vendor_id, code);
193 def = cfg_def->get(space, code);
198 if (!formatted_value.empty()) {
200 <<
" has a formatted value: '" << formatted_value
201 <<
"' but no option definition");
213 if (formatted_value.empty()) {
215 opt_desc.
option_ = def->optionFactory(universe, code, opt_desc.
option_->getData());
218 std::vector<std::string> split_vec;
219 boost::split(split_vec, formatted_value, boost::is_any_of(
","));
220 opt_desc.
option_ = def->optionFactory(universe, code, split_vec);
222 }
catch (
const std::exception& ex) {
224 <<
" from data specified, reason: " << ex.
what());
234 mergeInternal(options_, other.options_);
236 mergeInternal(vendor_options_, other.vendor_options_);
248 CfgOption::encapsulate() {
256 CfgOption::encapsulateInternal(
const std::string& option_space) {
261 for (OptionContainer::const_iterator opt = options->begin();
262 opt != options->end(); ++opt) {
263 encapsulateInternal(opt->option_);
268 CfgOption::encapsulateInternal(
const OptionPtr& option) {
270 const std::string& encap_space = option->getEncapsulatedSpace();
272 if (!encap_space.empty()) {
275 for (OptionContainer::const_iterator encap_opt =
276 encap_options->begin(); encap_opt != encap_options->end();
279 if (!option->getOption(encap_opt->option_->getType())) {
280 option->addOption(encap_opt->option_);
287 encapsulateInternal(encap_opt->option_);
293 template <
typename Selector>
296 OptionDescriptor, Selector>& src_container,
298 OptionDescriptor, Selector>& dest_container)
const {
300 std::list<Selector> selectors = src_container.getOptionSpaceNames();
305 for (
typename std::list<Selector>::const_iterator it = selectors.begin();
306 it != selectors.end(); ++it) {
314 for (OptionContainer::const_iterator src_opt = src_all->begin();
315 src_opt != src_all->end(); ++src_opt) {
318 idx.equal_range(src_opt->option_->getType());
321 if (std::distance(range.first, range.second) == 0) {
322 dest_container.addItem(OptionDescriptor(*src_opt), *it);
330 CfgOption::getAll(
const std::string& option_space)
const {
331 return (options_.getItems(option_space));
335 CfgOption::getAll(
const uint32_t vendor_id)
const {
336 return (vendor_options_.getItems(vendor_id));
340 CfgOption::del(
const std::string& option_space,
const uint16_t option_code) {
343 if (!options || options->empty()) {
354 auto option_space_names = getOptionSpaceNames();
355 for (
auto option_space_from_list : option_space_names) {
357 auto options_in_space = getAll(option_space_from_list);
358 for (
auto option_it = options_in_space->begin();
359 option_it != options_in_space->end();
364 if (option_it->option_ &&
365 (option_it->option_->getEncapsulatedSpace() == option_space)) {
366 option_it->option_->delOption(option_code);
372 auto& idx = options->get<1>();
373 return (idx.erase(option_code));
377 CfgOption::del(
const uint32_t vendor_id,
const uint16_t option_code) {
380 if (!vendor_options || vendor_options->empty()) {
385 auto& idx = vendor_options->get<1>();
386 return (idx.erase(option_code));
390 CfgOption::del(
const uint64_t
id) {
394 for (
auto space_name : getOptionSpaceNames()) {
396 auto options = getAll(space_name);
397 for (
auto option_it = options->begin(); option_it != options->end();
399 if (!option_it->option_) {
405 auto sub_options = option_it->option_->getOptions();
406 for (
auto sub = sub_options.begin(); sub != sub_options.end();
409 option_it->option_->delOption(sub->second->getType());
416 size_t num_deleted = options_.deleteItems(
id) + vendor_options_.deleteItems(
id);
422 return (num_deleted);
426 CfgOption::toElement()
const {
427 return (toElementWithMetadata(
false));
431 CfgOption::toElementWithMetadata(
const bool include_metadata)
const {
435 const std::list<std::string>& names = options_.getOptionSpaceNames();
436 for (std::list<std::string>::const_iterator name = names.begin();
437 name != names.end(); ++name) {
439 for (OptionContainer::const_iterator opt = opts->begin();
440 opt != opts->end(); ++opt) {
444 opt->contextToElement(map);
448 uint16_t code = opt->option_->getType();
453 def = LibDHCP::getRuntimeOptionDef(*name, code);
456 def = LibDHCP::getLastResortOptionDef(*name, code);
462 if (!opt->formatted_value_.empty()) {
467 std::vector<uint8_t> bin = opt->option_->toBinary();
475 if (include_metadata) {
476 map->set(
"metadata", opt->getMetadata());
484 const std::list<uint32_t>& ids = vendor_options_.getOptionSpaceNames();
485 for (std::list<uint32_t>::const_iterator
id = ids.begin();
486 id != ids.end(); ++id) {
488 for (OptionContainer::const_iterator opt = opts->begin();
489 opt != opts->end(); ++opt) {
493 opt->contextToElement(map);
495 std::ostringstream oss;
496 oss <<
"vendor-" << *id;
499 uint16_t code = opt->option_->getType();
504 LibDHCP::getVendorOptionDef(universe, *
id, code);
507 def = LibDHCP::getRuntimeOptionDef(oss.str(), code);
513 if (!opt->formatted_value_.empty()) {
518 std::vector<uint8_t> bin = opt->option_->toBinary();
OptionContainer::nth_index< 1 >::type OptionContainerTypeIndex
Type of the index #1 - option type.
boost::shared_ptr< OptionDescriptor > OptionDescriptorPtr
A pointer to option descriptor.
boost::shared_ptr< Option > OptionPtr
Universe
defines option universe DHCPv4 or DHCPv6
boost::shared_ptr< Element > ElementPtr
void copyTo(CfgOption &other) const
Copies this configuration to another configuration.
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
std::pair< OptionContainerTypeIndex::const_iterator, OptionContainerTypeIndex::const_iterator > OptionContainerTypeRange
Pair of iterators to represent the range of options having the same option type value.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
std::string formatted_value_
Option value in textual (CSV) format.
Represents option data configuration for the DHCP server.
bool persistent_
Persistence flag.
boost::shared_ptr< const Element > ConstElementPtr
void createOptions(CfgOptionDefPtr cfg_def)
Re-create the option in each descriptor based on given definitions.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
std::string space_name_
Option space name.
OptionPtr option_
Option instance.
void clearItems()
Remove all items from the container.
Defines the logger used by the top-level component of kea-dhcp-ddns.
string encodeHex(const vector< uint8_t > &binary)
Encode binary data in the base16 ('hex') format.
void merge(ElementPtr element, ConstElementPtr other)
Merges the data from other into element.
static ElementPtr create(const Position &pos=ZERO_POSITION())
void setId(const uint64_t id)
Sets element's database identifier.
#define DHCP6_OPTION_SPACE
boost::multi_index_container< OptionDescriptor, boost::multi_index::indexed_by< boost::multi_index::sequenced<>, boost::multi_index::hashed_non_unique< KeyFromKeyExtractor< boost::multi_index::const_mem_fun< Option, uint16_t,&Option::getType >, boost::multi_index::member< OptionDescriptor, OptionPtr,&OptionDescriptor::option_ > > >, boost::multi_index::hashed_non_unique< boost::multi_index::member< OptionDescriptor, bool,&OptionDescriptor::persistent_ > >, boost::multi_index::ordered_non_unique< boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime,&data::BaseStampedElement::getModificationTime > >, boost::multi_index::hashed_non_unique< boost::multi_index::tag< OptionIdIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, uint64_t,&data::BaseStampedElement::getId > > >> OptionContainer
Multi index container for DHCP option descriptors.
A generic exception that is thrown if a function is called in a prohibited way.
#define DHCP4_OPTION_SPACE
global std option spaces
boost::shared_ptr< OptionContainer > OptionContainerPtr
Pointer to the OptionContainer object.
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.