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
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
// Copyright (C) 2014-2024 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 <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/scoped_ptr.hpp><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <boost/shared_ptr.hpp><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <set><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <mutex><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <vector><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

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 Constructor.
    CfgHosts();

    /// @brief Destructor.
    virtual ~CfgHosts() { }<--- Destructor in derived class

    /// @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,<--- Function in derived class
           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,<--- Function in derived class
           const uint8_t* identifier_begin,
           const size_t identifier_len);

    /// @brief Return all hosts in a DHCPv4 subnet.
    ///
    /// This method returns all @c Host objects which represent reservations
    /// in a specified subnet.
    ///
    /// @param subnet_id Subnet identifier.
    ///
    /// @return Collection of const @c Host objects.
    virtual ConstHostCollection
    getAll4(const SubnetID& subnet_id) const;<--- Function in derived class

    /// @brief Return all hosts in a DHCPv4 subnet.
    ///
    /// This method returns all @c Host objects which represent reservations
    /// in a specified subnet.
    ///
    /// @param subnet_id Subnet identifier.
    ///
    /// @return Collection of non-const @c Host objects.
    virtual HostCollection
    getAll4(const SubnetID& subnet_id);<--- Function in derived class

    /// @brief Return all hosts in a DHCPv6 subnet.
    ///
    /// This method returns all @c Host objects which represent reservations
    /// in a specified subnet.
    ///
    /// @param subnet_id Subnet identifier.
    ///
    /// @return Collection of const @c Host objects.
    virtual ConstHostCollection
    getAll6(const SubnetID& subnet_id) const;<--- Function in derived class

    /// @brief Return all hosts in a DHCPv6 subnet.
    ///
    /// This method returns all @c Host objects which represent reservations
    /// in a specified subnet.
    ///
    /// @param subnet_id Subnet identifier.
    ///
    /// @return Collection of non-const @c Host objects.
    virtual HostCollection
    getAll6(const SubnetID& subnet_id);<--- Function in derived class

    /// @brief Return all hosts with a hostname.
    ///
    /// This method returns all @c Host objects which represent reservations
    /// using a specified hostname.
    ///
    /// @param hostname The lower case hostname.
    ///
    /// @return Collection of const @c Host objects.
    virtual ConstHostCollection
    getAllbyHostname(const std::string& hostname) const;<--- Function in derived class

    /// @brief Return all hosts with a hostname.
    ///
    /// This method returns all @c Host objects which represent reservations
    /// using a specified hostname.
    ///
    /// @param hostname The lower case hostname.
    ///
    /// @return Collection of @c Host objects.
    virtual HostCollection
    getAllbyHostname(const std::string& hostname);<--- Function in derived class

    /// @brief Return all hosts with a hostname in a DHCPv4 subnet.
    ///
    /// This method returns all @c Host objects which represent reservations
    /// using a specified hostname in a specified subnet.
    ///
    /// @param hostname The lower case hostname.
    /// @param subnet_id Subnet identifier.
    ///
    /// @return Collection of const @c Host objects.
    virtual ConstHostCollection
    getAllbyHostname4(const std::string& hostname, const SubnetID& subnet_id) const;<--- Function in derived class

    /// @brief Return all hosts with a hostname in a DHCPv4 subnet.
    ///
    /// This method returns all @c Host objects which represent reservations
    /// using a specified hostname in a specified subnet.
    ///
    /// @param hostname The lower case hostname.
    /// @param subnet_id Subnet identifier.
    ///
    /// @return Collection of @c Host objects.
    virtual HostCollection
    getAllbyHostname4(const std::string& hostname, const SubnetID& subnet_id);<--- Function in derived class

    /// @brief Return all hosts with a hostname in a DHCPv6 subnet.
    ///
    /// This method returns all @c Host objects which represent reservations
    /// using a specified hostname in a specified subnet.
    ///
    /// @param hostname The lower case hostname.
    /// @param subnet_id Subnet identifier.
    ///
    /// @return Collection of const @c Host objects.
    virtual ConstHostCollection
    getAllbyHostname6(const std::string& hostname, const SubnetID& subnet_id) const;<--- Function in derived class

    /// @brief Return all hosts with a hostname in a DHCPv6 subnet.
    ///
    /// This method returns all @c Host objects which represent reservations
    /// using a specified hostname in a specified subnet.
    ///
    /// @param hostname The lower case hostname.
    /// @param subnet_id Subnet identifier.
    ///
    /// @return Collection of @c Host objects.
    virtual HostCollection
    getAllbyHostname6(const std::string& hostname, const SubnetID& subnet_id);<--- Function in derived class

    /// @brief Returns range of hosts in a DHCPv4 subnet.
    ///
    /// This method returns a page of @c Host objects which represent
    /// reservations in a specified subnet.
    ///
    /// @param subnet_id Subnet identifier.
    /// @param source_index Index of the source (unused).
    /// @param lower_host_id Host identifier used as lower bound for the
    /// returned range.
    /// @param page_size maximum size of the page returned.
    ///
    /// @return Collection of const @c Host objects (may be empty).
    virtual ConstHostCollection
    getPage4(const SubnetID& subnet_id,<--- Function in derived class
             size_t& source_index,
             uint64_t lower_host_id,
             const HostPageSize& page_size) const;

    /// @brief Returns range of hosts in a DHCPv4 subnet.
    ///
    /// This method returns a page of @c Host objects which represent
    /// reservations in a specified subnet.
    ///
    /// @param subnet_id Subnet identifier.
    /// @param source_index Index of the source (unused).
    /// @param lower_host_id Host identifier used as lower bound for the
    /// returned range.
    /// @param page_size maximum size of the page returned.
    ///
    /// @return Collection of non-const @c Host objects (may be empty).
    virtual HostCollection
    getPage4(const SubnetID& subnet_id,<--- Function in derived class
             size_t& source_index,
             uint64_t lower_host_id,
             const HostPageSize& page_size);

    /// @brief Returns range of hosts in a DHCPv6 subnet.
    ///
    /// This method returns a page of @c Host objects which represent
    /// reservations in a specified subnet.
    ///
    /// @param subnet_id Subnet identifier.
    /// @param source_index Index of the source (unused).
    /// @param lower_host_id Host identifier used as lower bound for the
    /// returned range.
    /// @param page_size maximum size of the page returned.
    ///
    /// @return Collection of const @c Host objects (may be empty).
    virtual ConstHostCollection
    getPage6(const SubnetID& subnet_id,<--- Function in derived class
             size_t& source_index,
             uint64_t lower_host_id,
             const HostPageSize& page_size) const;

    /// @brief Returns range of hosts in a DHCPv6 subnet.
    ///
    /// This method returns a page of @c Host objects which represent
    /// reservations in a specified subnet.
    ///
    /// @param subnet_id Subnet identifier.
    /// @param source_index Index of the source (unused).
    /// @param lower_host_id Host identifier used as lower bound for the
    /// returned range.
    /// @param page_size maximum size of the page returned.
    ///
    /// @return Collection of non-const @c Host objects (may be empty).
    virtual HostCollection
    getPage6(const SubnetID& subnet_id,<--- Function in derived class
             size_t& source_index,
             uint64_t lower_host_id,
             const HostPageSize& page_size);

    /// @brief Returns range of hosts.
    ///
    /// This method returns a page of @c Host objects which represent
    /// reservations.
    ///
    /// @param source_index Index of the source (unused).
    /// @param lower_host_id Host identifier used as lower bound for the
    /// returned range.
    /// @param page_size maximum size of the page returned.
    ///
    /// @return Collection of const @c Host objects (may be empty).
    virtual ConstHostCollection
    getPage4(size_t& source_index,<--- Function in derived class
             uint64_t lower_host_id,
             const HostPageSize& page_size) const;

    /// @brief Returns range of hosts.
    ///
    /// This method returns a page of @c Host objects which represent
    /// reservations.
    ///
    /// @param source_index Index of the source (unused).
    /// @param lower_host_id Host identifier used as lower bound for the
    /// returned range.
    /// @param page_size maximum size of the page returned.
    ///
    /// @return Collection of non-const @c Host objects (may be empty).
    virtual HostCollection
    getPage4(size_t& source_index,<--- Function in derived class
             uint64_t lower_host_id,
             const HostPageSize& page_size);

    /// @brief Returns range of hosts.
    ///
    /// This method returns a page of @c Host objects which represent
    /// reservations.
    ///
    /// @param source_index Index of the source (unused).
    /// @param lower_host_id Host identifier used as lower bound for the
    /// returned range.
    /// @param page_size maximum size of the page returned.
    ///
    /// @return Collection of const @c Host objects (may be empty).
    virtual ConstHostCollection
    getPage6(size_t& source_index,<--- Function in derived class
             uint64_t lower_host_id,
             const HostPageSize& page_size) const;

    /// @brief Returns range of hosts.
    ///
    /// This method returns a page of @c Host objects which represent
    /// reservations.
    ///
    /// @param source_index Index of the source (unused).
    /// @param lower_host_id Host identifier used as lower bound for the
    /// returned range.
    /// @param page_size maximum size of the page returned.
    ///
    /// @return Collection of non-const @c Host objects (may be empty).
    virtual HostCollection
    getPage6(size_t& source_index,<--- Function in derived class
             uint64_t lower_host_id,
             const HostPageSize& page_size);

    /// @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;<--- Function in derived class

    /// @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);<--- Function in derived class

    /// @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;<--- Function in derived class

    /// @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.
    ///
    /// @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,<--- Function in derived class
         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,<--- Function in derived class
         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;<--- Function in derived class

    /// @brief Returns all hosts connected to the IPv4 subnet and having
    /// a reservation for a specified address.
    ///
    /// In most cases it is desired that there is at most one reservation
    /// for a given IPv4 address within a subnet. In a default configuration,
    /// the backend does not allow for inserting more than one host with
    /// the same IPv4 reservation. In that case, the number of hosts returned
    /// by this function is 0 or 1.
    ///
    /// If the backend is configured to allow multiple hosts with reservations
    /// for the same IPv4 address in the given subnet, this method can return
    /// more than one host.
    ///
    /// The typical use case when a single IPv4 address is reserved for multiple
    /// hosts is when these hosts represent different interfaces of the same
    /// machine and each interface comes with a different MAC address. In that
    /// case, the same IPv4 address is assigned regardless of which interface is
    /// used by the DHCP client to communicate with the server.
    ///
    /// @param subnet_id Subnet identifier.
    /// @param address reserved IPv4 address.
    ///
    /// @return Collection of const @c Host objects.
    virtual ConstHostCollection
    getAll4(const SubnetID& subnet_id,<--- Function in derived class
            const asiolink::IOAddress& address) 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 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,<--- Function in derived class
         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,<--- Function in derived class
         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;<--- Function in derived class

    /// @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);<--- Function in derived class

    /// @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;<--- Function in derived class

    /// @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);<--- Function in derived class

    /// @brief Returns all hosts connected to the IPv6 subnet and having
    /// a reservation for a specified address or delegated prefix (lease).
    ///
    /// In most cases it is desired that there is at most one reservation
    /// for a given IPv6 lease within a subnet. In a default configuration,
    /// the backend does not allow for inserting more than one host with
    /// the same IPv6 address or prefix. In that case, the number of hosts
    /// returned by this function is 0 or 1.
    ///
    /// If the backend is configured to allow multiple hosts with reservations
    /// for the same IPv6 lease in the given subnet, this method can return
    /// more than one host.
    ///
    /// The typical use case when a single IPv6 lease is reserved for multiple
    /// hosts is when these hosts represent different interfaces of the same
    /// machine and each interface comes with a different MAC address. In that
    /// case, the same IPv6 lease is assigned regardless of which interface is
    /// used by the DHCP client to communicate with the server.
    ///
    /// @param subnet_id Subnet identifier.
    /// @param address reserved IPv6 address/prefix.
    ///
    /// @return Collection of const @c Host objects.
    virtual ConstHostCollection
    getAll6(const SubnetID& subnet_id,<--- Function in derived class
            const asiolink::IOAddress& address) const;

    /// @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);<--- Function in derived class

    /// @brief Attempts to delete hosts 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);<--- Function in derived class

    /// @brief Attempts to delete all hosts for a given IPv4 subnet.
    ///
    /// @param subnet_id Identifier of the subnet for which reservation should
    /// be deleted.
    /// @return Number of deleted hosts.
    virtual size_t delAll4(const SubnetID& subnet_id);

    /// @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,<--- Function in derived class
                      const Host::IdentifierType& identifier_type,
                      const uint8_t* identifier_begin, const size_t identifier_len);

    /// @brief Attempts to delete all hosts for a given IPv6 subnet.
    ///
    /// @param subnet_id Identifier of the subnet for which reservation should
    /// be deleted.
    /// @return Number of deleted hosts.
    virtual size_t delAll6(const SubnetID& subnet_id);

    /// @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,<--- Function in derived class
                      const Host::IdentifierType& identifier_type,
                      const uint8_t* identifier_begin, const size_t identifier_len);

    /// @brief Attempts to update an existing host entry.
    ///
    /// The implementation is common to multiple host data sources, so let's
    /// provide it in the base host data source. In some instances, it may
    /// require synchronization e.g. with transactions in case of databases.
    ///
    /// @param host the host up to date with the requested changes
    virtual void update(HostPtr const& host);<--- Function in derived class

    /// @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 {<--- Function in derived class
        return (std::string("configuration file"));
    }

    /// @brief Controls whether IP reservations are unique or non-unique.
    ///
    /// In a typical case, the IP reservations are unique and backends verify
    /// prior to adding a host reservation to the database that the reservation
    /// for a given IP address/subnet does not exist. In some cases it may be
    /// required to allow non-unique IP reservations, e.g. in the case when a
    /// host has several interfaces and independently of which interface is used
    /// by this host to communicate with the DHCP server the same IP address
    /// should be assigned. In this case the @c unique value should be set to
    /// false to disable the checks for uniqueness on the backend side.
    ///
    /// @param unique boolean flag indicating if the IP reservations must be
    /// unique or can be non-unique.
    /// @return always true because this data source supports both the case when
    /// the addresses must be unique and when they may be non-unique.
    virtual bool setIPReservationsUnique(const bool unique);<--- Function in derived class

    /// @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;<--- Function in derived class

private:

    /// @note: all private/internal methods suppose the caller takes
    /// the mutex at the exception of toElement[46].

    /// @brief Returns @c Host objects for the specific identifier and type.
    ///
    /// This private method is called by the @c CfgHosts::getAll
    /// 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 in a DHCPv4 subnet.
    ///
    /// This private method is called by the @c CfgHosts::getAll4
    /// method which finds the @c Host objects in a specified subnet.
    /// The retrieved objects are appended to the @c storage container.
    ///
    /// @param subnet_id Subnet 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 getAllInternal4(const SubnetID& subnet_id,
                         Storage& storage) const;

    /// @brief Returns @c Host objects in a DHCPv6 subnet.
    ///
    /// This private method is called by the @c CfgHosts::getAll6
    /// method which finds the @c Host objects in a specified subnet.
    /// The retrieved objects are appended to the @c storage container.
    ///
    /// @param subnet_id Subnet 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 getAllInternal6(const SubnetID& subnet_id,
                         Storage& storage) const;

    /// @brief Return all hosts with a hostname.
    ///
    /// This private method is called by the @c CfgHosts::getAllbyHostname
    /// method which finds the @c Host objects in a specified subnet.
    /// The retrieved objects are appended to the @c storage container.
    ///
    /// @param hostname The lower case hostname.
    /// @param [out] storage Container to which the retrieved objects are
    /// appended.
    /// @tparam One of the @c ConstHostCollection of @c HostCollection.
    template<typename Storage>
    void getAllbyHostnameInternal(const std::string& hostname,
                                  Storage& storage) const;

    /// @brief Return all hosts with a hostname and a DHCPv4 subnet.
    ///
    /// This private method is called by the @c CfgHosts::getAllbyHostname4
    /// method which finds the @c Host objects in a specified subnet.
    /// The retrieved objects are appended to the @c storage container.
    ///
    /// @param hostname The lower case hostname.
    /// @param subnet_id Subnet 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 getAllbyHostnameInternal4(const std::string& hostname,
                                   const SubnetID& subnet_id,
                                   Storage& storage) const;

    /// @brief Return all hosts with a hostname and a DHCPv6 subnet.
    ///
    /// This private method is called by the @c CfgHosts::getAllbyHostname6
    /// method which finds the @c Host objects in a specified subnet.
    /// The retrieved objects are appended to the @c storage container.
    ///
    /// @param hostname The lower case hostname.
    /// @param subnet_id Subnet 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 getAllbyHostnameInternal6(const std::string& hostname,
                                   const SubnetID& subnet_id,
                                   Storage& storage) const;

    /// @brief Returns a page of @c Host objects in a DHCPv4 subnet.
    ///
    /// This private method is called by the @c CfgHosts::getPage4
    /// method which finds the @c Host objects in a specified subnet.
    /// The retrieved objects are appended to the @c storage container.
    ///
    /// @param subnet_id Subnet identifier.
    /// @param lower_host_id Host identifier used as lower bound for the
    /// returned range.
    /// @param page_size maximum size of the page returned.
    /// @param [out] storage Container to which the retrieved objects are
    /// appended.
    /// @tparam One of the @c ConstHostCollection of @c HostCollection.
    template<typename Storage>
    void getPageInternal4(const SubnetID& subnet_id,
                          uint64_t lower_host_id,
                          const HostPageSize& page_size,
                          Storage& storage) const;

    /// @brief Returns a page of @c Host objects in a DHCPv6 subnet.
    ///
    /// This private method is called by the @c CfgHosts::getPage6
    /// method which finds the @c Host objects in a specified subnet.
    /// The retrieved objects are appended to the @c storage container.
    ///
    /// @param subnet_id Subnet identifier.
    /// @param lower_host_id Host identifier used as lower bound for the
    /// returned range.
    /// @param page_size maximum size of the page returned.
    /// @param [out] storage Container to which the retrieved objects are
    /// appended.
    /// @tparam One of the @c ConstHostCollection of @c HostCollection.
    template<typename Storage>
    void getPageInternal6(const SubnetID& subnet_id,
                          uint64_t lower_host_id,
                          const HostPageSize& page_size,
                          Storage& storage) const;

    /// @brief Returns a page of @c Host objects.
    ///
    /// This private method is called by the @c CfgHosts::getPage4
    /// and @c CfgHosts::getPage6 methods which find the @c Host objects.
    /// The retrieved objects are appended to the @c storage container.
    ///
    /// @param lower_host_id Host identifier used as lower bound for the
    /// returned range.
    /// @param page_size maximum size of the page returned.
    /// @param [out] storage Container to which the retrieved objects are
    /// appended.
    /// @tparam One of the @c ConstHostCollection of @c HostCollection.
    template<typename Storage>
    void getPageInternal(uint64_t lower_host_id,
                         const HostPageSize& page_size,
                         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::getAll4 methods
    /// to retrieve the @c Host for which the specified IPv4 address is
    /// reserved and is in specified subnet-id. The retrieved objects are
    /// appended to the returned container.
    ///
    /// @param subnet_id Subnet identifier.
    /// @param address IPv4 address.
    /// @return Collection of const @c Host objects.
    ConstHostCollection
    getAllInternal4(const SubnetID& subnet_id,
		    const asiolink::IOAddress& address) 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 Next host id.
    uint64_t next_host_id_ = 0;

    /// @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
    /// - subnet ID
    /// - host ID
    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 Holds the setting whether the IP reservations must be unique or
    /// may be non-unique.
    bool ip_reservations_unique_ = true;

    /// @brief The mutex used to protect host containers.
    const boost::scoped_ptr<std::mutex> mutex_;

    /// @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