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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
|
// Copyright (C) 2014-2018 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 HOST_MGR_H
#define HOST_MGR_H
#include <database/database_connection.h>
#include <dhcpsrv/base_host_data_source.h>
#include <dhcpsrv/cache_host_data_source.h>
#include <dhcpsrv/host.h>
#include <dhcpsrv/subnet_id.h>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#include <string>
namespace isc {
namespace dhcp {
/// @brief Host Manager.
///
/// This is a singleton class which provides access to multiple sources of
/// information about static host reservations. These sources are also referred
/// to as host data sources. Each source derives (directly or indirectly) from
/// the @c BaseHostDataSource.
///
/// The @c HostMgr is a central point for providing information about the host
/// reservations. Internally, it relays the queries (calls to the appropriate
/// methods declared in the @c BaseHostDataSource) to the data sources it is
/// connected to. The @c HostMgr is always connected to the server's
/// configuration, accessible through the @c CfgHosts object in the @c CfgMgr.
/// The @c CfgHosts object holds all reservations specified in the DHCP server
/// configuration file. If a particular reservation is not found in the
/// @c CfgHosts object, the @c HostMgr will try to find it using alternate
/// host data storages. An alternate host data storage is usually a database
/// (e.g. SQL database), accessible through a dedicated host data source
/// object (a.k.a. database backend). This datasource is responsible for
/// managing the connection with the database and forming appropriate queries
/// to retrieve (or update) the information about the reservations.
///
/// The use of alternate host data sources is optional and usually requires
/// additional configuration to be specified by the server administrator.
/// For example, for the SQL database the user's credentials, database address,
/// and database name are required. The @c HostMgr passes these parameters
/// to an appropriate datasource which is responsible for opening a connection
/// and maintaining it.
///
/// It is possible to switch to different alternate data sources or disable
/// the use of alternate datasources, e.g. as a result of server's
/// reconfiguration. However, the use of the primary host data source (i.e.
/// reservations specified in the configuration file) can't be disabled.
class HostMgr : public boost::noncopyable, public BaseHostDataSource {
public:
/// @brief Creates new instance of the @c HostMgr.
///
/// If an instance of the @c HostMgr already exists, it will be replaced
/// by the new instance. Thus, any instances of alternate host data
/// sources will be dropped.
///
static void create();
/// @brief Add an alternate host backend (aka host data source).
///
/// @param access Host backend access parameters for the alternate
/// host backend. It holds "keyword=value" pairs, separated by spaces.
/// The supported values are specific to the alternate backend in use.
/// However, the "type" parameter will be common and it will specify which
/// backend is to be used. Currently, no parameters are supported
/// and the parameter is ignored.
static void addBackend(const std::string& access);
/// @brief Delete an alternate host backend (aka host data source).
///
/// @param db_type database backend type.
/// @return true when found and removed, false when not found.
static bool delBackend(const std::string& db_type);
/// @brief Delete all alternate backends.
static void delAllBackends();
/// @brief Check for the cache host backend.
///
/// Checks if the first host backend implements
/// the cache abstract class and sets cache_ptr_.
///
/// @param logging When true (not the default) emit an informational log.
/// @return true if the first host backend is a cache.
static bool checkCacheBackend(bool logging = false);
/// @brief Returns a sole instance of the @c HostMgr.
///
/// This method should be used to retrieve an instance of the @c HostMgr
/// to be used to gather/manage host reservations. It returns an instance
/// of the @c HostMgr created by the @c create method. If such instance
/// doesn't exist yet, it is created using the @c create method with the
/// default value of the data access string, which configures the host
/// manager to not use the alternate host data source.
static HostMgr& instance();
/// @brief Return all hosts connected to any subnet for which reservations
/// have been made using a specified identifier.
///
/// This method returns all @c Host objects representing reservations for
/// a specified identifier as documented in the
/// @c BaseHostDataSource::getAll.
///
/// It retrieves reservations from both primary and alternate host data
/// source as a single collection of @c Host objects, i.e. if matching
/// reservations are in both sources, all of them are returned. The
/// reservations from the primary data source are placed before the
/// reservations from the alternate source.
///
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return Collection of const @c Host objects.
virtual ConstHostCollection
getAll(const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin,
const size_t identifier_len) const;
/// @brief Returns a collection of hosts using the specified IPv4 address.
///
/// This method may return multiple @c Host objects if they are connected to
/// different subnets.
///
/// If matching reservations are both in the primary and the alternate
/// data source, all of them are returned. The reservations from the
/// primary data source are placed before the reservations from the
/// alternate source.
///
/// @param address IPv4 address for which the @c Host object is searched.
///
/// @return Collection of const @c Host objects.
virtual ConstHostCollection
getAll4(const asiolink::IOAddress& address) const;
/// @brief Returns any host connected to the IPv4 subnet.
///
/// This method returns a single reservation for a particular host as
/// documented in the @c BaseHostDataSource::get4 even when the
/// reservation is marked as from negative caching. This allows to
/// monitor negative caching.
///
/// @param subnet_id Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return Const @c Host object for which reservation has been made using
/// the specified identifier.
virtual ConstHostPtr
get4Any(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin,
const size_t identifier_len) const;
/// @brief Returns a host connected to the IPv4 subnet.
///
/// This method returns a single reservation for a particular host as
/// documented in the @c BaseHostDataSource::get4.
///
/// @param subnet_id Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return Const @c Host object for which reservation has been made using
/// the specified identifier.
virtual ConstHostPtr
get4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len) const;
/// @brief Returns a host connected to the IPv4 subnet and having
/// a reservation for a specified IPv4 address.
///
/// This method returns a single reservation for the particular host
/// (identified by the HW address or DUID) as documented in the
/// @c BaseHostDataSource::get4.
///
/// @param subnet_id Subnet identifier.
/// @param address reserved IPv4 address.
///
/// @return Const @c Host object using a specified IPv4 address.
virtual ConstHostPtr
get4(const SubnetID& subnet_id, const asiolink::IOAddress& address) const;
/// @brief Returns any host connected to the IPv6 subnet.
///
/// This method returns a host connected to the IPv6 subnet as described
/// in the @c BaseHostDataSource::get6 even when the
/// reservation is marked as from negative caching. This allows to
/// monitor negative caching.
///
/// @param subnet_id Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return Const @c Host object for which reservation has been made using
/// the specified identifier.
virtual ConstHostPtr
get6Any(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin,
const size_t identifier_len) const;
/// @brief Returns a host connected to the IPv6 subnet.
///
/// This method returns a host connected to the IPv6 subnet as described
/// in the @c BaseHostDataSource::get6.
///
/// @param subnet_id Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return Const @c Host object for which reservation has been made using
/// the specified identifier.
virtual ConstHostPtr
get6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len) const;
/// @brief Returns a host using the specified IPv6 prefix.
///
/// This method returns a host using specified IPv6 prefix, as described
/// in the @c BaseHostDataSource::get6.
///
/// @param prefix IPv6 prefix for which the @c Host object is searched.
/// @param prefix_len IPv6 prefix length.
///
/// @return Const @c Host object using a specified IPv6 prefix.
virtual ConstHostPtr
get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len) const;
/// @brief Returns a host from specific subnet and reserved address.
///
/// @param subnet_id subnet identifier.
/// @param addr specified address.
///
/// @return Const @c host object that has a reservation for specified address.
virtual ConstHostPtr
get6(const SubnetID& subnet_id, const asiolink::IOAddress& addr) const;
/// @brief Adds a new host to the alternate data source.
///
/// This method will throw an exception if no alternate data source is
/// in use.
///
/// @param host Pointer to the new @c Host object being added.
virtual void add(const HostPtr& host);
/// @brief Attempts to delete a host by address.
///
/// This method supports both v4 and v6.
///
/// @param subnet_id subnet identifier.
/// @param addr specified address.
/// @return true if deletion was successful, false otherwise.
virtual bool del(const SubnetID& subnet_id, const asiolink::IOAddress& addr);
/// @brief Attempts to delete a host by (subnet4-id, identifier, identifier-type)
///
/// This method supports v4 only.
///
/// @param subnet_id IPv4 Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
/// @return true if deletion was successful, false otherwise.
virtual bool
del4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len);
/// @brief Attempts to delete a host by (subnet6-id, identifier, identifier-type)
///
/// This method supports v6 only.
///
/// @param subnet_id IPv6 Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
/// @return true if deletion was successful, false otherwise.
virtual bool
del6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len);
/// @brief Return backend type
///
/// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
///
/// @return Type of the backend.
virtual std::string getType() const {
return (std::string("host_mgr"));
}
/// @brief Returns the host data source list.
///
/// @return reference to the host data source list.
HostDataSourceList& getHostDataSourceList() {
return (alternate_sources_);
}
/// @brief Returns the first host data source.
///
/// May return NULL if the host data source list is empty.
/// @return pointer to the first host data source (or NULL).
HostDataSourcePtr getHostDataSource() const;
/// @brief Returns the negative caching flag.
///
/// @return the negative caching flag.
bool getNegativeCaching() const {
return (negative_caching_);
}
/// @brief Sets the negative caching flag.
///
void setNegativeCaching(bool negative_caching) {
negative_caching_ = negative_caching;
}
protected:
/// @brief The negative caching flag.
///
/// When true and the first backend is a cache
/// negative answers are inserted in the cache.
/// This works for get[46] for a subnet and an identifier.
bool negative_caching_;
/// @brief Cache an answer.
///
/// @param host Pointer to the missied host.
virtual void cache(ConstHostPtr host) const;
/// @brief Cache a negative answer.
///
/// @param ipv4_subnet_id Identifier of the IPv4 subnet.
/// @param ipv6_subnet_id Identifier of the IPv6 subnet.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of the Identifier.
/// @param identifier_len Identifier length.
virtual void cacheNegative(const SubnetID& ipv4_subnet_id,
const SubnetID& ipv6_subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin,
const size_t identifier_len) const;
private:
/// @brief Private default constructor.
HostMgr() : negative_caching_(false) { }
/// @brief List of alternate host data sources.
HostDataSourceList alternate_sources_;
/// @brief Pointer to the cache.
CacheHostDataSourcePtr cache_ptr_;
/// @brief Returns a pointer to the currently used instance of the
/// @c HostMgr.
static boost::scoped_ptr<HostMgr>& getHostMgrPtr();
};
}
}
#endif // HOST_MGR_H
|