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
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
|
// Copyright (C) 2014-2017 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 CFG_HOSTS_H
#define CFG_HOSTS_H
#include <asiolink/io_address.h>
#include <cc/cfg_to_element.h>
#include <dhcp/duid.h>
#include <dhcp/hwaddr.h>
#include <dhcpsrv/base_host_data_source.h>
#include <dhcpsrv/host.h>
#include <dhcpsrv/host_container.h>
#include <dhcpsrv/subnet_id.h>
#include <dhcpsrv/writable_host_data_source.h>
#include <boost/shared_ptr.hpp>
#include <vector>
namespace isc {
namespace dhcp {
/// @brief Represents the host reservations specified in the configuration file.
///
/// This class holds a collection of the host reservations (@c Host objects)
/// which can be retrieved using different search criteria.
///
/// In the typical case the reservations are searched using the client's MAC
/// address or DUID and a subnet that the client is connected to. The
/// reservations can be also retrieved using other parameters, such as reserved
/// IP address.
///
/// The reservations are added to this object by the configuration parsers,
/// when the new configuration is applied for the server. The reservations
/// are retrieved by the @c HostMgr class when the server is allocating or
/// renewing an address or prefix for the particular client.
class CfgHosts : public BaseHostDataSource, public WritableHostDataSource,
public isc::data::CfgToElement {
public:
/// @brief Destructor.
virtual ~CfgHosts() { }
/// @brief Return all hosts for the specified HW address or DUID.
///
/// This method returns all @c Host objects which represent reservations
/// for the specified HW address or DUID. Note, that this method may
/// return multiple reservations because a particular client may have
/// reservations in multiple subnets and the same client may be identified
/// by HW address or DUID. The server is unable to verify that the specific
/// DUID and HW address belong to the same client, until the client sends
/// a DHCP message.
///
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available, e.g. DHCPv4 client case.
///
/// @return Collection of const @c Host objects.
virtual ConstHostCollection
getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid = DuidPtr()) const;
/// @brief Non-const version of the @c getAll const method.
///
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available, e.g. DHCPv4 client case.
///
/// @return Collection of non-const @c Host objects.
virtual HostCollection
getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid = DuidPtr());
/// @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 which represent reservations
/// for a specified identifier. This method may return multiple hosts
/// because a particular client may have reservations in multiple subnets.
///
/// @param identifier_type One of the supported identifier types.
/// @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 Non-const version of the @c getAll const method.
///
/// This method returns all @c Host objects which represent reservations
/// for a specified identifier. This method may return multiple hosts
/// because a particular client may have reservations in multiple subnets.
///
/// @param identifier_type One of the supported identifier types.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return Collection of non-const @c Host objects.
virtual HostCollection
getAll(const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin,
const size_t identifier_len);
/// @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.
///
/// @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 a collection of hosts using the specified IPv4 address.
///
/// This method may return multiple @c Host objects if they are connected
/// to different subnets.
///
/// @param address IPv4 address for which the @c Host object is searched.
///
/// @return Collection of const @c Host objects.
virtual HostCollection
getAll4(const asiolink::IOAddress& address);
/// @brief Returns a collection of hosts using the specified IPv6 address.
///
/// This method may return multiple @c Host objects if they are connected
/// to different subnets.
///
/// @param address IPv6 address for which the @c Host object is searched.
///
/// @return Collection of const @c Host objects.
virtual ConstHostCollection
getAll6(const asiolink::IOAddress& address) const;
/// @brief Returns a collection of hosts using the specified IPv6 address.
///
/// This method may return multiple @c Host objects if they are connected
/// to different subnets.
///
/// @param address IPv6 address for which the @c Host object is searched.
///
/// @return Collection of const @c Host objects.
virtual HostCollection
getAll6(const asiolink::IOAddress& address);
/// @brief Returns a host connected to the IPv4 subnet and matching
/// specified identifiers.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available.
///
/// @return Const @c Host object using a specified HW address or DUID.
/// @throw isc::dhcp::DuplicateHost if more than one candidate host has
/// been found.
virtual ConstHostPtr
get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid = DuidPtr()) const;
/// @brief Returns a host connected to the IPv4 subnet and matching
/// specified identifiers.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available.
///
/// @return Non-const @c Host object using a specified HW address or DUID.
/// @throw isc::dhcp::DuplicateHost if more than one candidate host has
/// been found.
virtual HostPtr
get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid = DuidPtr());
/// @brief Returns a host connected to the IPv4 subnet.
///
/// @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.
///
/// @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 Non-const @c Host object for which reservation has been made
/// using the specified identifier.
virtual HostPtr
get4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len);
/// @brief Returns a host connected to the IPv4 subnet and having
/// a reservation for a specified IPv4 address.
///
/// @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 a host connected to the IPv6 subnet and matching
/// the specified identifiers.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid DUID or NULL if not available.
///
/// @return Const @c Host object using a specified HW address or DUID.
/// @throw isc::dhcp::DuplicateHost if more than one candidate host has
/// been found.
virtual ConstHostPtr
get6(const SubnetID& subnet_id, const DuidPtr& duid,
const HWAddrPtr& hwaddr = HWAddrPtr()) const;
/// @brief Returns a host connected to the IPv6 subnet and matching the
/// specified identifiers.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid DUID or NULL if not available.
///
/// @return Non-const @c Host object using a specified HW address or DUID.
/// @throw isc::dhcp::DuplicateHost if more than one candidate host has
/// been found.
virtual HostPtr
get6(const SubnetID& subnet_id, const DuidPtr& duid,
const HWAddrPtr& hwaddr = HWAddrPtr());
/// @brief Returns a host connected to the IPv6 subnet.
///
/// @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 connected to the IPv6 subnet.
///
/// @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 Non-const @c Host object for which reservation has been made
/// using the specified identifier.
virtual HostPtr
get6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len);
/// @brief Returns a host using the specified IPv6 prefix.
///
/// @param prefix IPv6 prefix for which the @c Host object is searched.
/// @param prefix_len IPv6 prefix length.
///
/// @return Const @c Host object for which specified prefix is reserved.
virtual ConstHostPtr
get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len) const;
/// @brief Returns a host using the specified IPv6 prefix.
///
/// @param prefix IPv6 prefix for which the @c Host object is searched.
/// @param prefix_len IPv6 prefix length.
///
/// @return Non-const @c Host object for which specified prefix is
/// reserved.
virtual HostPtr
get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len);
/// @brief Returns a host connected to the IPv6 subnet and having
/// a reservation for a specified IPv6 address.
///
/// @param subnet_id Subnet identifier.
/// @param address reserved IPv6 address.
///
/// @return Const @c Host object using a specified IPv6 address.
virtual ConstHostPtr
get6(const SubnetID& subnet_id, const asiolink::IOAddress& address) const;
/// @brief Returns a host connected to the IPv6 subnet and having
/// a reservation for a specified IPv6 address.
///
/// @param subnet_id Subnet identifier.
/// @param address reserved IPv6 address.
///
/// @return Const @c Host object using a specified IPv6 address.
virtual HostPtr
get6(const SubnetID& subnet_id, const asiolink::IOAddress& address);
/// @brief Adds a new host to the collection.
///
/// @param host Pointer to the new @c Host object being added.
///
/// @throw DuplicateHost If a host for a particular HW address or DUID
/// has already been added to the IPv4 or IPv6 subnet.
virtual void add(const HostPtr& host);
/// @brief Attempts to delete a host by address.
///
/// This method supports both v4 and v6.
/// @todo: Not implemented.
///
/// @param subnet_id subnet identifier.
/// @param addr specified address.
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.
/// @todo: Not implemented.
///
/// @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.
/// @todo: Not implemented.
///
/// @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("configuration file"));
}
/// @brief Unparse a configuration object
///
/// host reservation lists are not autonomous so they are
/// not returned directly but with the subnet where they are
/// declared as:
/// @code
/// [
/// { "id": 123, "reservations": [ <resv1>, <resv2> ] },
/// { "id": 456, "reservations": [ <resv3 ] },
/// ...
/// ]
/// @endcode
///
/// @ref isc::dhcp::CfgHostsList can be used to handle this
///
/// @return a pointer to unparsed configuration
isc::data::ElementPtr toElement() const;
private:
/// @brief Returns @c Host objects for the specific identifier and type.
///
/// This private method is called by the @c CfgHosts::getAllInternal
/// method which finds the @c Host objects using specified identifier.
/// The retrieved objects are appended to the @c storage container.
///
/// @param identifier_type The type of the supplied identifier.
/// @param identifier Pointer to a first byte of the identifier.
/// @param identifier_len Length of the identifier.
/// @param [out] storage Container to which the retrieved objects are
/// appended.
/// @tparam One of the @c ConstHostCollection of @c HostCollection.
template<typename Storage>
void getAllInternal(const Host::IdentifierType& identifier_type,
const uint8_t* identifier,
const size_t identifier_len,
Storage& storage) const;
/// @brief Returns @c Host objects for the specified HW address or DUID.
///
/// This private method is called by the @c CfgHosts::getAll methods to
/// retrieve the @c Host objects using HW address or DUID. The retrieved
/// objects are appended to the @c storage container.
///
/// @param hwaddr HW address identifying a host.
/// @param duid DUID identifying a host.
/// @param [out] storage Container to which the retrieved objects are
/// appended.
/// @tparam One of the @c ConstHostCollection or @c HostCollection.
template<typename Storage>
void getAllInternal(const HWAddrPtr& hwaddr, const DuidPtr& duid,
Storage& storage) const;
/// @brief Returns @c Host objects for the specified IPv4 address.
///
/// This private method is called by the @c CfgHosts::getAll4 methods
/// to retrieve the @c Host for which the specified IPv4 address is
/// reserved. The retrieved objects are appended to the @c storage
/// container.
///
/// @param address IPv4 address.
/// @param [out] storage Container to which the retrieved objects are
/// appended.
/// @tparam One of the @c ConstHostCollection or @c HostCollection.
template<typename Storage>
void getAllInternal4(const asiolink::IOAddress& address,
Storage& storage) const;
/// @brief Returns @c Host objects for the specified IPv6 address.
///
/// This private method is called by the @c CfgHosts::getAll6 methods
/// to retrieve the @c Host for which the specified IPv6 address is
/// reserved. The retrieved objects are appended to the @c storage
/// container.
///
/// @param address IPv6 address.
/// @param [out] storage Container to which the retrieved objects are
/// appended.
/// @tparam One of the @c ConstHostCollection or @c HostCollection.
template<typename Storage>
void getAllInternal6(const asiolink::IOAddress& address,
Storage& storage) const;
/// @brief Returns @c Host objects for the specified (Subnet-id,IPv6 address) tuple.
///
/// This private method is called by the @c CfgHosts::getAll6 methods
/// to retrieve the @c Host for which the specified IPv6 address is
/// reserved and is in specified subnet-id. The retrieved objects are
/// appended to the @c storage container.
///
/// @param subnet_id Subnet Identifier.
/// @param address IPv6 address.
/// @param [out] storage Container to which the retrieved objects are
/// appended.
/// @tparam One of the @c ConstHostCollection or @c HostCollection.
template<typename Storage>
void
getAllInternal6(const SubnetID& subnet_id,
const asiolink::IOAddress& address,
Storage& storage) const;
/// @brief Returns @c Host object connected to a subnet.
///
/// This private method returns a pointer to the @c Host object using
/// a specified identifier and connected to an IPv4 or IPv6 subnet.
///
/// @param subnet_id IPv4 or IPv6 subnet identifier.
/// @param subnet6 A boolean flag which indicates if the subnet identifier
/// points to a IPv4 (if false) or IPv6 subnet (if true).
/// @param identifier_type Identifier type.
/// @param identifier Pointer to a first byte of the buffer holding an
/// identifier.
/// @param identifier_len Identifier length.
///
/// @return Pointer to the found host, or NULL if no host found.
/// @throw isc::dhcp::DuplicateHost if method found more than one matching
/// @c Host object.
HostPtr
getHostInternal(const SubnetID& subnet_id, const bool subnet6,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier,
const size_t identifier_len) const;
/// @brief Returns the @c Host object holding reservation for the IPv6
/// address and connected to the specific subnet.
///
/// This private method is called by the public @c get6 method variants.
///
/// @param subnet_id IPv6 subnet identifier.
/// @param address IPv6 address.
/// @tparam ReturnType One of @c HostPtr or @c ConstHostPtr
/// @tparam One of the @c ConstHostCollection or @c HostCollection.
///
/// @return Pointer to the found host, or NULL if no host found.
/// @throw isc::dhcp::DuplicateHost if method found more than one matching
/// @c Host object.
template<typename ReturnType, typename Storage>
ReturnType getHostInternal6(const SubnetID& subnet_id,
const asiolink::IOAddress& address) const;
template<typename ReturnType>
ReturnType getHostInternal6(const asiolink::IOAddress& prefix,
const uint8_t prefix_len) const;
/// @brief Adds a new host to the collection.
///
/// This is an internal method called by public @ref add. Contrary to its
/// name, this is useful for both IPv4 and IPv6 hosts, as this adds the
/// host to hosts_ storage that is shared by both families. Notes that
/// for IPv6 host additional steps may be required (see @ref add6).
///
/// @param host Pointer to the new @c Host object being added.
///
/// @throw DuplicateHost If a host for a particular HW address or DUID
/// has already been added to the IPv4 subnet.
virtual void add4(const HostPtr& host);
/// @brief Adds IPv6-specific reservation to hosts collection.
///
/// This is an internal method called by public @ref add. This method adds
/// IPv6 reservations (IPv6 addresses or prefixes reserved) to the hosts6_
/// storage. Note the host has been added to the hosts_ already (in @ref add4).
///
/// @param host Pointer to the new @c Host object being added.
///
/// @throw DuplicateHost If a host for a particular HW address or DUID
/// or for the particular address or prefix has already been added to
/// the IPv6 subnet.
virtual void add6(const HostPtr& host);
/// @brief Multi-index container holding @c Host objects.
///
/// It can be used for finding hosts by the following criteria:
/// - IPv4 address
/// - DUID
/// - HW/MAC address
HostContainer hosts_;
/// @brief Multi-index container holding @c Host objects with v6 reservations.
///
/// It can be used for finding hosts by the following criteria:
/// - IPv6 address
/// - IPv6 prefix
HostContainer6 hosts6_;
/// @brief Unparse a configuration object (DHCPv4 reservations)
///
/// @return a pointer to unparsed configuration
isc::data::ElementPtr toElement4() const;
/// @brief Unparse a configuration object (DHCPv6 reservations)
///
/// @return a pointer to unparsed configuration
isc::data::ElementPtr toElement6() const;
};
/// @name Pointers to the @c CfgHosts objects.
//@{
/// @brief Non-const pointer.
typedef boost::shared_ptr<CfgHosts> CfgHostsPtr;
/// @brief Const pointer.
typedef boost::shared_ptr<const CfgHosts> ConstCfgHostsPtr;
//@}
}
}
#endif // CFG_HOSTS_H
|