cfgmgr.cc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <asiolink/io_address.h>
  15. #include <dhcp/iface_mgr.h>
  16. #include <dhcp/libdhcp++.h>
  17. #include <dhcpsrv/cfgmgr.h>
  18. #include <dhcpsrv/dhcpsrv_log.h>
  19. #include <dhcpsrv/subnet_id.h>
  20. #include <string>
  21. using namespace isc::asiolink;
  22. using namespace isc::util;
  23. namespace isc {
  24. namespace dhcp {
  25. const size_t CfgMgr::CONFIG_LIST_SIZE = 10;
  26. CfgMgr&
  27. CfgMgr::instance() {
  28. static CfgMgr cfg_mgr;
  29. return (cfg_mgr);
  30. }
  31. void
  32. CfgMgr::addOptionSpace4(const OptionSpacePtr& space) {
  33. if (!space) {
  34. isc_throw(InvalidOptionSpace,
  35. "provided option space object is NULL.");
  36. }
  37. OptionSpaceCollection::iterator it = spaces4_.find(space->getName());
  38. if (it != spaces4_.end()) {
  39. isc_throw(InvalidOptionSpace, "option space " << space->getName()
  40. << " already added.");
  41. }
  42. spaces4_.insert(make_pair(space->getName(), space));
  43. }
  44. void
  45. CfgMgr::addOptionSpace6(const OptionSpacePtr& space) {
  46. if (!space) {
  47. isc_throw(InvalidOptionSpace,
  48. "provided option space object is NULL.");
  49. }
  50. OptionSpaceCollection::iterator it = spaces6_.find(space->getName());
  51. if (it != spaces6_.end()) {
  52. isc_throw(InvalidOptionSpace, "option space " << space->getName()
  53. << " already added.");
  54. }
  55. spaces6_.insert(make_pair(space->getName(), space));
  56. }
  57. std::string CfgMgr::getDataDir() {
  58. return (datadir_);
  59. }
  60. bool
  61. CfgMgr::isDuplicate(const Subnet6& subnet) const {
  62. for (Subnet6Collection::const_iterator subnet_it = subnets6_.begin();
  63. subnet_it != subnets6_.end(); ++subnet_it) {
  64. if ((*subnet_it)->getID() == subnet.getID()) {
  65. return (true);
  66. }
  67. }
  68. return (false);
  69. }
  70. void
  71. CfgMgr::setD2ClientConfig(D2ClientConfigPtr& new_config) {
  72. d2_client_mgr_.setD2ClientConfig(new_config);
  73. }
  74. bool
  75. CfgMgr::ddnsEnabled() {
  76. return (d2_client_mgr_.ddnsEnabled());
  77. }
  78. const D2ClientConfigPtr&
  79. CfgMgr::getD2ClientConfig() const {
  80. return (d2_client_mgr_.getD2ClientConfig());
  81. }
  82. D2ClientMgr&
  83. CfgMgr::getD2ClientMgr() {
  84. return (d2_client_mgr_);
  85. }
  86. void
  87. CfgMgr::ensureCurrentAllocated() {
  88. if (!configuration_ || configs_.empty()) {
  89. configuration_.reset(new SrvConfig());
  90. configs_.push_back(configuration_);
  91. }
  92. }
  93. void
  94. CfgMgr::clear() {
  95. configs_.clear();
  96. ensureCurrentAllocated();
  97. }
  98. void
  99. CfgMgr::commit() {
  100. ensureCurrentAllocated();
  101. if (!configs_.back()->sequenceEquals(*configuration_)) {
  102. configuration_ = configs_.back();
  103. // Keep track of the maximum size of the configs history. Before adding
  104. // new element, we have to remove the oldest one.
  105. if (configs_.size() > CONFIG_LIST_SIZE) {
  106. SrvConfigList::iterator it = configs_.begin();
  107. std::advance(it, configs_.size() - CONFIG_LIST_SIZE);
  108. configs_.erase(configs_.begin(), it);
  109. }
  110. }
  111. }
  112. void
  113. CfgMgr::rollback() {
  114. ensureCurrentAllocated();
  115. if (!configuration_->sequenceEquals(*configs_.back())) {
  116. configs_.pop_back();
  117. }
  118. }
  119. void
  120. CfgMgr::revert(const size_t index) {
  121. ensureCurrentAllocated();
  122. if (index == 0) {
  123. isc_throw(isc::OutOfRange, "invalid commit index 0 when reverting"
  124. " to an old configuration");
  125. } else if (index > configs_.size() - 1) {
  126. isc_throw(isc::OutOfRange, "unable to revert to commit index '"
  127. << index << "', only '" << configs_.size() - 1
  128. << "' previous commits available");
  129. }
  130. // Let's rollback an existing configuration to make sure that the last
  131. // configuration on the list is the current one. Note that all remaining
  132. // operations in this function should be exception free so there shouldn't
  133. // be a problem that the revert operation fails and the staging
  134. // configuration is destroyed by this rollback.
  135. rollback();
  136. // Get the iterator to the current configuration and then advance to the
  137. // desired one.
  138. SrvConfigList::const_reverse_iterator it = configs_.rbegin();
  139. std::advance(it, index);
  140. // Copy the desired configuration to the new staging configuration. The
  141. // staging configuration is re-created here because we rolled back earlier
  142. // in this function.
  143. (*it)->copy(*getStagingCfg());
  144. // Make the staging configuration a current one.
  145. commit();
  146. }
  147. ConstSrvConfigPtr
  148. CfgMgr::getCurrentCfg() {
  149. ensureCurrentAllocated();
  150. return (configuration_);
  151. }
  152. SrvConfigPtr
  153. CfgMgr::getStagingCfg() {
  154. ensureCurrentAllocated();
  155. if (configuration_->sequenceEquals(*configs_.back())) {
  156. uint32_t sequence = configuration_->getSequence();
  157. configs_.push_back(SrvConfigPtr(new SrvConfig(++sequence)));
  158. }
  159. return (configs_.back());
  160. }
  161. CfgMgr::CfgMgr()
  162. : datadir_(DHCP_DATA_DIR), echo_v4_client_id_(true),
  163. d2_client_mgr_(), verbose_mode_(false) {
  164. // DHCP_DATA_DIR must be set set with -DDHCP_DATA_DIR="..." in Makefile.am
  165. // Note: the definition of DHCP_DATA_DIR needs to include quotation marks
  166. // See AM_CPPFLAGS definition in Makefile.am
  167. }
  168. CfgMgr::~CfgMgr() {
  169. }
  170. }; // end of isc::dhcp namespace
  171. }; // end of isc namespace