summaryrefslogtreecommitdiffstats
path: root/src/lib/dhcpsrv/network_state.h
blob: def52e682c3367204e3fadf0d319d9711cb8b622 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
// Copyright (C) 2017-2021 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 Holds information about DHCP service enabling status.
///
/// When the DHCP server receives a command to disable DHCP service entirely
/// or for specific networks, this has to be recorded to allow for re-enabling
/// DHCP service for these networks as a result of receiving a command from
/// the administrator or when the timeout for re-enabling the service occurs.
/// Currently there are two types of command originating either from user or
/// HA internal mechanism.
/// The global state can also be altered by the DB recovery mechanism which
/// disables the service on connection loss and re-enables it after the
/// connection is restored. Because the server supports recovery for multiple
/// connections, this is implemented using an internal counter.
/// Combining all the origins of the alteration of the network state, the
/// behavior is:
/// a) the network state is disabled if any of the originators explicitly set
///    the disabled flag.
/// b) the network state is restored only if all originators explicitly clear
///    the disabled flag.
/// In the future, it will be possible to specify "disabled" parameter for
/// a subnet (or network) in the configuration file to indicate that this subnet
/// should be excluded from the service. When a command is subsequently sent to
/// temporarily disable a service for some other subnets for a specified amount
/// of time, only these subnets should be re-enabled when the time elapses. This
/// class fulfills this requirement by recording the subnets disabled with a command
/// and re-enabling them when required. The subnets specified as "disabled" in
/// the configuration file should remain disabled until explicitly enabled with a
/// control command.
///
/// This class also allows for disabling the DHCP service globally. In this case
/// the server drops all received packets.
///
/// The "dhcp-disable" and "dhcp-enable" commands are used for globally disabling
/// and enabling the DHCP service. The "dhcp-disable-scopes" and "dhcp-enable-scopes"
/// commands are used to disable and enable DHCP service for subnets and networks.
/// In case of the "dhcp-disable" and "dhcp-disable-scopes" commands, it is possible
/// to specify "max-period" parameter which provides a timeout, after which the
/// settings are reverted (service is re-enabled globally and/or for specific
/// scopes).
///
/// Disabling DHCP service with a timeout is useful to guard against issues when
/// the controlling client dies after disabling the DHCP service on the server,
/// e.g. failover peers may instruct each other to disable the DHCP service while
/// database synchronization takes place. If the peer subsequently dies, the
/// surviving server must re-enable DHCP on its own.
///
/// @todo This class currently supports only the case of globally disabling
/// the DHCP service. Disabling per network/subnet will be added later.
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.
    enum class Origin {
        /// @brief The network state is being altered by a user command.
        USER_COMMAND,
        /// @brief The network state is being altered by a HA internal command.
        HA_COMMAND,
        /// @brief The network state is being altered by the DB connection
        /// recovery mechanics.
        DB_CONNECTION
    };

    /// @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(const NetworkState::Origin& 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(const NetworkState::Origin& origin);

    /// @brief Reset internal counters.
    ///
    /// Reset internal counters for a specific 'origin' after the server has
    /// been reconfigured or all the connections have been restored.
    ///
    /// @param type The origin for which the state flags need to be reset.
    void reset(const NetworkState::Origin& type);

    /// @brief Enables DHCP service globally and for scopes which have been
    /// disabled as a result of control command.
    ///
    /// @param origin The origin of the state transition.
    void enableAll(const NetworkState::Origin& origin);

    /// @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 delayedEnableAll(const unsigned int seconds,
                          const NetworkState::Origin& 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 enableAll function will be called automatically.
    ///
    /// @return true if delayed enabling of the DHCP service is scheduled,
    /// false otherwise.
    bool isDelayedEnableAll() 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