diff --git a/src/bin/dhcp4/dhcp4_messages.mes b/src/bin/dhcp4/dhcp4_messages.mes index 28256e948e..0e2f2e7946 100644 --- a/src/bin/dhcp4/dhcp4_messages.mes +++ b/src/bin/dhcp4/dhcp4_messages.mes @@ -392,6 +392,11 @@ for decline4 hook point and one of the callouts set next step status to DROP. The server will now abort processing of the packet as if it was never received. The lease will continue to be assigned to this client. +% DHCP4_HOOK_DDNS_UPDATE A hook has updated the DDNS parameters: hostname %1=>%2, forward update %3=>%4, reverse update %5=>%6 +This message indicates that there was a hook called on ddns_update hook point +and that hook updated the DDNS update parameters: hostname, or whether to +conduct forward (A record) or reverse (PTR record) DDNS updates. + % DHCP4_HOOK_LEASE4_RELEASE_SKIP %1: lease was not released because a callout set the next step to SKIP This debug message is printed when a callout installed on lease4_release hook point set the next step status to SKIP. For this particular hook point, the diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index 62f957fcd7..4d645565db 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -94,6 +94,7 @@ struct Dhcp4Hooks { int hook_index_buffer4_send_; ///< index for "buffer4_send" hook point int hook_index_lease4_decline_; ///< index for "lease4_decline" hook point int hook_index_host4_identifier_; ///< index for "host4_identifier" hook point + int hook_index_ddns_update_; ///< index for "ddns_update" hook point /// Constructor that registers hook points for DHCPv4 engine Dhcp4Hooks() { @@ -106,6 +107,7 @@ struct Dhcp4Hooks { hook_index_buffer4_send_ = HooksManager::registerHook("buffer4_send"); hook_index_lease4_decline_ = HooksManager::registerHook("lease4_decline"); hook_index_host4_identifier_ = HooksManager::registerHook("host4_identifier"); + hook_index_ddns_update_ = HooksManager::registerHook("ddns_update"); } }; @@ -2096,6 +2098,43 @@ Dhcpv4Srv::processClientName(Dhcpv4Exchange& ex) { } } + // Optionally, call a hook that may possibly override the decisions made + // earlier. + if (HooksManager::calloutsPresent(Hooks.hook_index_ddns_update_)) { + Pkt4Ptr query = ex.getQuery(); + + CalloutHandlePtr callout_handle = getCalloutHandle(query); + + // Pass incoming packet as argument + callout_handle->setArgument("query4", query); + callout_handle->setArgument("response4", resp); + callout_handle->setArgument("hostname", hostname); + callout_handle->setArgument("fwd-update", fqdn_fwd); + callout_handle->setArgument("rev-update", fqdn_rev); + + // Call callouts + HooksManager::callCallouts(Hooks.hook_index_ddns_update_, *callout_handle); + + // Let's get the parameters returned by hook. + string hook_hostname; + bool hook_fqdn_fwd = false; + bool hook_fqdn_rev = false; + callout_handle->getArgument("hostname", hook_hostname); + callout_handle->getArgument("fwd-update", hook_fqdn_fwd); + callout_handle->getArgument("rev-update", hook_fqdn_rev); + + // If there's anything changed by the hook, log it and then update the parameters + if ( (hostname != hook_hostname) || (fqdn_fwd != hook_fqdn_fwd) || + (fqdn_rev != hook_fqdn_rev)) { + LOG_DEBUG(hooks_logger, DBGLVL_PKT_HANDLING, DHCP4_HOOK_DDNS_UPDATE) + .arg(hostname).arg(hook_hostname).arg(fqdn_fwd).arg(hook_fqdn_fwd) + .arg(fqdn_rev).arg(hook_fqdn_rev); + hostname = hook_hostname; + fqdn_fwd = hook_fqdn_fwd; + fqdn_rev = hook_fqdn_rev; + } + } + // Update the context auto ctx = ex.getContext(); ctx->fwd_dns_update_ = fqdn_fwd;