summaryrefslogtreecommitdiffstats
path: root/src/lib/dhcpsrv/network_state.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dhcpsrv/network_state.h')
-rw-r--r--src/lib/dhcpsrv/network_state.h216
1 files changed, 216 insertions, 0 deletions
diff --git a/src/lib/dhcpsrv/network_state.h b/src/lib/dhcpsrv/network_state.h
new file mode 100644
index 0000000..861d1a7
--- /dev/null
+++ b/src/lib/dhcpsrv/network_state.h
@@ -0,0 +1,216 @@
+// Copyright (C) 2017-2023 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
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef NETWORK_STATE_H
+#define NETWORK_STATE_H
+
+#include <cc/data.h>
+#include <dhcpsrv/subnet_id.h>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+#include <set>
+#include <mutex>
+#include <string>
+
+namespace isc {
+namespace dhcp {
+
+class NetworkStateImpl;
+
+/// @brief Controls the DHCP service enabling status.
+///
+/// Sometimes, a DHCP server must pause responding to the DHCP queries.
+/// Typical cases include a database connection loss when the server tries
+/// to reconnect and various cases related to the High Availability operation.
+/// It is also possible to explicitly turn the DHCP service on and off via the
+/// control channel. This class receives calls from different origins to
+/// disable and re-enable the DHCP service.
+///
+/// The general rule is that the DHCP service must be disabled when the class
+/// receives at least one request to disable the service from any origin. The
+/// service must be re-enabled when all requestors previously disabling the
+/// service re-enabled it. This class also allows for specifying a timeout value
+/// for each request, after which the service gets re-enabled automatically. It
+/// is particularly useful in HA when there is no guarantee that the HA partner
+/// will be able to re-enable the service because it may experience an unexpected
+/// outage. In that case, the "max-period" parameter must accompany the "dhcp-disable"
+/// command to ensure that the service will eventually be re-enabled.
+
+/// The HA hook library may include several independent relationships. Each
+/// relationship is treated as a separate origin by this class. If one relationship
+/// disables the DHCP service, the service must remain disabled even when any other
+/// relationship requests enabling it. The service is re-enabled after all
+/// relationships requested re-enabling it (e.g., they all finished synchronizing
+/// the lease database).
+///
+/// The HA service instances must have unique identifiers they use to specify the
+/// origin. For example, an @c HAService with the identifier of 1 should request
+/// disabling the local service like this:
+///
+/// @code
+/// NetworkState state;
+/// state.disableService(NetworkState::HA_LOCAL_COMMAND + 1);
+/// @endcode
+///
+/// The DHCP state can also be altered by the database recovery mechanism, which
+/// disables the service on connection loss and re-enables it after the connection
+/// is restored. Unlike in HA, this is implemented using an internal counter. In
+/// this case, there is one origin for all database connections. The requests for
+/// the @c NetworkState::DB_CONNECTION are counted, and the DHCP service is
+/// re-enabled when the counter reaches 0.
+///
+/// @todo We should consider migrating the database recovery to the same mechanism
+/// we use for the HA. The reference counting works because the database connection
+/// classes ensure that for each request to disable the DHCP service, there is a
+/// corresponding request to enable the service. It prevents the situation that the
+/// service remains disabled because there were more requests to disable than to
+/// enable the service. It is hard to ensure the same consistency for the HA.
+class NetworkState {
+public:
+
+ /// @brief DHCP server type.
+ enum ServerType {
+ DHCPv4,
+ DHCPv6
+ };
+
+ /// @brief Origin of the network state transition.
+ ///
+ /// The enumeration indicates the originator of the state transition of the
+ /// network state: either user command, HA internal command or DB connection
+ /// recovery mechanism.
+
+ /// @brief The network state is being altered by a user command.
+ ///
+ /// Specify unique origins for different commands by adding a number to this
+ /// constant.
+ static const unsigned int USER_COMMAND = 1;
+
+ /// @brief The network state is being altered by an HA internal command.
+ ///
+ /// Specify HA service-specific origins by adding a unique local service
+ /// identifier to this constant.
+ static const unsigned int HA_LOCAL_COMMAND = 1000;
+
+ /// @brief The network state is being altered by a "dhcp-disable" or "dhcp-enable"
+ /// command sent by a HA partner.
+ ///
+ /// Specify HA service-specific origins by adding a unique remote service
+ /// identifier to this constant.
+ static const unsigned int HA_REMOTE_COMMAND = 2000;
+
+ /// @brief The network state is being altered by the DB connection
+ /// recovery mechanics.
+ static const unsigned int DB_CONNECTION = 3000;
+
+ /// @brief Type of the container holding collection of subnet identifiers.
+ typedef std::set<SubnetID> Subnets;
+
+ /// @brief Type of the container holding collection of shared network names.
+ typedef std::set<std::string> Networks;
+
+ /// @brief Constructor.
+ NetworkState(const ServerType& server_type);
+
+ /// @brief Disable the DHCP service state for respective transition origin.
+ ///
+ /// @note If any of the user commands, HA internal commands or connection
+ /// recovery processes disable the dhcp service, the service will remain
+ /// disabled until all flags are cleared.
+ ///
+ /// @param origin The origin of the state transition.
+ void disableService(unsigned int origin);
+
+ /// @brief Enable the DHCP service state for respective transition origin.
+ ///
+ /// @note If any of the user commands, HA internal commands or connection
+ /// recovery processes disable the dhcp service, the service will remain
+ /// disabled until all flags are cleared.
+ ///
+ /// @param origin The origin of the state transition.
+ void enableService(unsigned int origin);
+
+ /// @brief Reset internal counters for database connection.
+ ///
+ /// It results in enabling the network service if network service for
+ /// all other origins is enabled.
+ void resetForDbConnection();
+
+ /// @brief Schedules enabling DHCP service in the future.
+ ///
+ /// @param seconds Number of seconds after which the service should be enabled
+ /// unless @c enableAll is enabled before that time.
+ /// @param origin The origin of the state transition.
+ void delayedEnableService(const unsigned int seconds,
+ unsigned int origin);
+
+ /// @brief Checks if the DHCP service is globally enabled.
+ ///
+ /// @return true if the service is globally enabled, false otherwise.
+ bool isServiceEnabled() const;
+
+ /// @brief Checks if delayed enabling of DHCP services is scheduled.
+ ///
+ /// It indicates that the timer is present which counts the time until
+ /// @c delayedEnable function will be called automatically.
+ ///
+ /// @return true if delayed enabling of the DHCP service is scheduled,
+ /// false otherwise.
+ bool isDelayedEnableService() const;
+
+ /// @name Selective disabling/enabling DHCP service per scopes
+ //@{
+
+ /// @brief Disable DHCP service for selected subnets.
+ ///
+ /// @param subnets Collection of subnet identifiers for which the service
+ /// should be disabled.
+ ///
+ /// @throw isc::NotImplemented
+ void selectiveDisable(const NetworkState::Subnets& subnets);
+
+ /// @brief Disable DHCP service for selected networks.
+ ///
+ /// @param networks Collection of shared network names for which the service
+ /// should be disabled.
+ ///
+ /// @throw isc::NotImplemented
+ void selectiveDisable(const NetworkState::Networks& networks);
+
+ /// @brief Enable DHCP service for selected subnets.
+ ///
+ /// @param subnets Collection of subnet identifiers for which the service
+ /// should be disabled.
+ ///
+ /// @throw isc::NotImplemented
+ void selectiveEnable(const NetworkState::Subnets& subnets);
+
+ /// @brief Enable DHCP service for selected networks.
+ ///
+ /// @param networks Collection of shared network names for which the service
+ /// should be enabled.
+ ///
+ /// @throw isc::NotImplemented
+ void selectiveEnable(const NetworkState::Networks& networks);
+
+ //@}
+
+private:
+
+ /// @brief Pointer to the @c NetworkState implementation.
+ boost::shared_ptr<NetworkStateImpl> impl_;
+
+ /// @brief The mutex used to protect internal state.
+ const boost::scoped_ptr<std::mutex> mutex_;
+};
+
+/// @brief Pointer to the @c NetworkState object.
+typedef boost::shared_ptr<NetworkState> NetworkStatePtr;
+
+} // end of namespace isc::dhcp
+} // end of namespace isc
+
+#endif // NETWORK_STATE_H