Kea 3.3.1
sanity_checker.cc
Go to the documentation of this file.
1// Copyright (C) 2018-2022 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6#include <config.h>
7
10#include <dhcpsrv/cfgmgr.h>
11#include <dhcpsrv/subnet_id.h>
12#include <dhcpsrv/dhcpsrv_log.h>
13#include <process/daemon.h>
14#include <sstream>
15
16namespace isc {
17namespace dhcp {
18
21 return (false);
22 }
23
24 SrvConfigPtr cfg;
25 if (current) {
27 } else {
29 }
30
31 if (cfg) {
32 CfgConsistencyPtr sanity = cfg->getConsistency();
33 return (sanity && (sanity->getLeaseSanityCheck() != CfgConsistency::LEASE_CHECK_NONE));
34 }
35
36 return (false);
37}
38
39void SanityChecker::checkLease(Lease4Ptr& lease, bool current) {
40 SrvConfigPtr cfg;
41 if (current) {
43 } else {
45 }
46
47 CfgConsistencyPtr sanity = cfg->getConsistency();
48 if (sanity->getLeaseSanityCheck() == CfgConsistency::LEASE_CHECK_NONE) {
49 // No sense going farther.
50 return;
51 }
52
53 CfgSubnets4Ptr subnets = cfg->getCfgSubnets4();
54 checkLeaseInternal(lease, sanity, subnets);
55}
56
57void SanityChecker::checkLease(Lease6Ptr& lease, bool current) {
58 // We only check IA_NAs currently.
59 if (lease->type_ != Lease::TYPE_NA) {
60 return;
61 }
62
63 SrvConfigPtr cfg;
64 if (current) {
66 } else {
68 }
69 CfgConsistencyPtr sanity = cfg->getConsistency();
70 if (sanity->getLeaseSanityCheck() == CfgConsistency::LEASE_CHECK_NONE) {
71 // No sense going farther.
72 return;
73 }
74
75 CfgSubnets6Ptr subnets = cfg->getCfgSubnets6();
76 checkLeaseInternal(lease, sanity, subnets);
77}
78
79template<typename LeasePtrType, typename SubnetsType>
80void SanityChecker::checkLeaseInternal(LeasePtrType& lease, const CfgConsistencyPtr& checks,
81 const SubnetsType& subnets) {
82
83 auto subnet = subnets->getBySubnetId(lease->subnet_id_);
84 if (subnet && subnet->inRange(lease->addr_)) {
85
86 // If the subnet is defined and the address is in range, we're good.
87
88 return;
89 }
90
91 // Ok, if we got here, that means that either we did not find a subnet
92 // of found it, but it wasn't the right subnet.
93 SubnetID id = findSubnetId(lease, subnets);
94
95 // Prepare a message in the case the check fails.
96 std::ostringstream msg;
97 if (id != 0) {
98 msg << "the lease should have subnet-id " << id;
99 } else {
100 msg << "the lease IP address did not belong to a configured subnet";
101 }
102
103 switch (checks->getLeaseSanityCheck()) {
105 if (lease->subnet_id_ != id) {
106 // Print a warning, but return the lease as is.
108 .arg(lease->addr_.toText())
109 .arg(lease->subnet_id_)
110 .arg(msg.str());
111 }
112 break;
113
115 if (lease->subnet_id_ != id) {
116
117 // If there is a better subnet, use it.
118 if (id != 0) {
120 .arg(lease->addr_.toText())
121 .arg(lease->subnet_id_)
122 .arg(id);
123 lease->subnet_id_ = id;
124 } else {
125 // If not, return the lease as is.
127 .arg(lease->addr_.toText())
128 .arg(lease->subnet_id_)
129 .arg(msg.str());
130 }
131 }
132 break;
133
135 if (lease->subnet_id_ != id) {
136
137 // If there is a better subnet, use it.
138 if (id != 0) {
140 .arg(lease->addr_.toText())
141 .arg(lease->subnet_id_)
142 .arg(id);
143 lease->subnet_id_ = id;
144 break;
145 } else {
146 // If not, delete the lease.
148 .arg(lease->addr_.toText())
149 .arg(lease->subnet_id_)
150 .arg(msg.str());
151 lease.reset();
152 }
153
154 }
155 break;
156
158 if (lease->subnet_id_ != id) {
160 .arg(lease->addr_.toText())
161 .arg(lease->subnet_id_)
162 .arg(msg.str());
163 lease.reset();
164 }
165 break;
166
167 default:
168 // Shouldn't get here but some compilers and analyzers
169 // complain. We'll we treat it as NONE and return the
170 // lease as-is.
171 break;
172
173 }
174
175 // Additional checks may be implemented in the future here.
176
179}
180
181template<typename LeaseType, typename SubnetsType>
182SubnetID SanityChecker::findSubnetId(const LeaseType& lease, const SubnetsType& subnets) {
183 auto subnet = subnets->selectSubnet(lease->addr_);
184 if (!subnet) {
185 return (0);
186 }
187
188 return (subnet->getID());
189}
190
191}
192}
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition cfgmgr.cc:29
SrvConfigPtr getStagingCfg()
Returns a pointer to the staging configuration.
Definition cfgmgr.cc:121
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Definition cfgmgr.cc:116
void checkLease(Lease4Ptr &lease, bool current=true)
Sanity checks and possibly corrects an IPv4 lease.
static bool leaseCheckingEnabled(bool current=true)
Indicates the specified configuration enables lease sanity checking.
static bool getCBRepairMode()
Get the CB repair mode flag.
Definition daemon.h:282
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition macros.h:20
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition macros.h:26
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition dhcpsrv_log.h:56
const isc::log::MessageID DHCPSRV_LEASE_SANITY_FAIL_DISCARD
const isc::log::MessageID DHCPSRV_LEASE_SANITY_FAIL
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition lease.h:528
boost::shared_ptr< SrvConfig > SrvConfigPtr
Non-const pointer to the SrvConfig.
boost::shared_ptr< CfgSubnets6 > CfgSubnets6Ptr
Non-const pointer.
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition subnet_id.h:25
boost::shared_ptr< CfgSubnets4 > CfgSubnets4Ptr
Non-const pointer.
boost::shared_ptr< CfgConsistency > CfgConsistencyPtr
Type used to for pointing to CfgConsistency structure.
const isc::log::MessageID DHCPSRV_LEASE_SANITY_FIXED
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition lease.h:315
Defines the logger used by the top-level component of kea-lfc.
@ TYPE_NA
the lease contains non-temporary IPv6 address
Definition lease.h:47