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
|
// Copyright (C) 2015 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/.
#include <config.h>
#include <dhcp/option_data_types.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/dhcpsrv_log.h>
#include <dhcpsrv/d2_client_mgr.h>
#include <dhcpsrv/ncr_generator.h>
#include <stdint.h>
#include <vector>
using namespace isc;
using namespace isc::dhcp;
using namespace isc::dhcp_ddns;
namespace {
/// @brief Sends name change request to D2 using lease information.
///
/// This method is exception safe.
///
/// @param lease Pointer to a lease for which NCR should be sent.
/// @param identifier Identifier to be used to generate DHCID for
/// the DNS update. For DHCPv4 it will be hardware address or client
/// identifier. For DHCPv6 it will be a DUID.
/// @param label Client identification information in the textual format.
/// This is used for logging purposes.
///
/// @tparam LeasePtrType Pointer to a lease.
/// @tparam IdentifierType HW Address, Client Identifier or DUID.
template<typename LeasePtrType, typename IdentifierType>
void queueNCRCommon(const NameChangeType& chg_type, const LeasePtrType& lease,
const IdentifierType& identifier, const std::string& label) {
// Check if there is a need for update.
if (lease->hostname_.empty() || (!lease->fqdn_fwd_ && !lease->fqdn_rev_)
|| !CfgMgr::instance().getD2ClientMgr().ddnsEnabled()) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_QUEUE_NCR_SKIP)
.arg(label)
.arg(lease->addr_.toText());
return;
}
try {
// Create DHCID
std::vector<uint8_t> hostname_wire;
OptionDataTypeUtil::writeFqdn(lease->hostname_, hostname_wire, true);
D2Dhcid dhcid = D2Dhcid(identifier, hostname_wire);
// Create name change request.
NameChangeRequestPtr ncr
(new NameChangeRequest(chg_type, lease->fqdn_fwd_, lease->fqdn_rev_,
lease->hostname_, lease->addr_.toText(),
dhcid, lease->cltt_ + lease->valid_lft_,
lease->valid_lft_));
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL_DATA, DHCPSRV_QUEUE_NCR)
.arg(label)
.arg(chg_type == CHG_ADD ? "add" : "remove")
.arg(ncr->toText());
// Send name change request.
CfgMgr::instance().getD2ClientMgr().sendRequest(ncr);
} catch (const std::exception& ex) {
LOG_ERROR(dhcpsrv_logger, DHCPSRV_QUEUE_NCR_FAILED)
.arg(label)
.arg(chg_type == CHG_ADD ? "add" : "remove")
.arg(lease->addr_.toText())
.arg(ex.what());
}
}
} // end of anonymous namespace
namespace isc {
namespace dhcp {
void queueNCR(const NameChangeType& chg_type, const Lease4Ptr& lease) {
if (lease) {
// Client id takes precedence over HW address.
if (lease->client_id_) {
queueNCRCommon(chg_type, lease, lease->client_id_->getClientId(),
Pkt4::makeLabel(lease->hwaddr_, lease->client_id_));
} else {
// Client id is not specified for the lease. Use HW address
// instead.
queueNCRCommon(chg_type, lease, lease->hwaddr_,
Pkt4::makeLabel(lease->hwaddr_, lease->client_id_));
}
}
}
void queueNCR(const NameChangeType& chg_type, const Lease6Ptr& lease) {
// DUID is required to generate NCR.
if (lease && (lease->type_ != Lease::TYPE_PD) && lease->duid_) {
queueNCRCommon(chg_type, lease, *(lease->duid_),
Pkt6::makeLabel(lease->duid_, lease->hwaddr_));
}
}
}
}
|