return (ia_rsp);
}
- // Keep the old data in case the callout tells us to skip update
+ // Keep the old data in case the callout tells us to skip update.
Lease6 old_data = *lease;
- // At this point, we have to make make some decisions with respect to the
- // FQDN option that we have generated as a result of receiving client's
- // FQDN. In particular, we have to get to know if the DNS update will be
- // performed or not. It is possible that option is NULL, which is valid
- // condition if client didn't request DNS updates and server didn't force
- // the update.
- bool do_fwd = false;
- bool do_rev = false;
- Option6ClientFqdnPtr fqdn = boost::dynamic_pointer_cast<
- Option6ClientFqdn>(answer->getOption(D6O_CLIENT_FQDN));
- if (fqdn) {
- CfgMgr::instance().getD2ClientMgr().getUpdateDirections(*fqdn,
- do_fwd, do_rev);
- }
+ bool invalid_addr = false;
+ // Check what address the client has sent. The address should match the one
+ // that we have associated with the IAID. If it doesn't match we have two
+ // options: allocate the address for the client, if the server's
+ // configuration allows to do so, or notify the client that his address is
+ // wrong. For now we will just notify the client that the address is wrong,
+ // but both solutions require that we check the contents of the IA_NA option
+ // sent by the client. Without this check we would extend the existing lease
+ // even if the address being carried in the IA_NA is different than the
+ // one we are extending.
+ Option6IAAddrPtr iaaddr = boost::dynamic_pointer_cast<
+ Option6IAAddr>(ia->getOption(D6O_IAADDR));
+ if (iaaddr && (iaaddr->getAddress() != lease->addr_)) {
+ Option6IAAddrPtr zero_lft_addr(new Option6IAAddr(D6O_IAADDR,
+ iaaddr->getAddress(),
+ 0, 0));
+ ia_rsp->addOption(zero_lft_addr);
+ // Mark that the client's notion of the address is invalid, so as
+ // we don't update the actual client's lease.
+ invalid_addr = true;
- std::string hostname;
- if (do_fwd || do_rev) {
- hostname = fqdn->getDomainName();
- }
+ } else {
- // At this point, we have to make make some decisions with respect
- // to the FQDN option that we have generated as a result of receiving
- // If the new FQDN settings have changed for the lease, we need to
- // delete any existing FQDN records for this lease.
- if ((lease->hostname_ != hostname) || (lease->fqdn_fwd_ != do_fwd) ||
- (lease->fqdn_rev_ != do_rev)) {
- LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL,
- DHCP6_DDNS_LEASE_RENEW_FQDN_CHANGE)
- .arg(lease->toText())
- .arg(hostname)
- .arg(do_rev ? "true" : "false")
- .arg(do_fwd ? "true" : "false");
++ // At this point, we have to make make some decisions with respect to
++ // the FQDN option that we have generated as a result of receiving
+ // client's FQDN. In particular, we have to get to know if the DNS
+ // update will be performed or not. It is possible that option is NULL,
+ // which is valid condition if client didn't request DNS updates and
+ // server didn't force the update.
+ bool do_fwd = false;
+ bool do_rev = false;
+ Option6ClientFqdnPtr fqdn = boost::dynamic_pointer_cast<
+ Option6ClientFqdn>(answer->getOption(D6O_CLIENT_FQDN));
+ if (fqdn) {
- // For now, we assert that if we are doing forward we are also
- // doing reverse.
- if (fqdn->getFlag(Option6ClientFqdn::FLAG_S)) {
- do_fwd = true;
- do_rev = true;
- }
++ CfgMgr::instance().getD2ClientMgr().getUpdateDirections(*fqdn,
++ do_fwd,
++ do_rev);
+ }
- createRemovalNameChangeRequest(lease);
- }
+ std::string hostname;
+ if (do_fwd || do_rev) {
+ hostname = fqdn->getDomainName();
+ }
+
+ // If the new FQDN settings have changed for the lease, we need to
+ // delete any existing FQDN records for this lease.
+ if ((lease->hostname_ != hostname) || (lease->fqdn_fwd_ != do_fwd) ||
+ (lease->fqdn_rev_ != do_rev)) {
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL,
+ DHCP6_DDNS_LEASE_RENEW_FQDN_CHANGE)
+ .arg(lease->toText())
+ .arg(hostname)
+ .arg(do_rev ? "true" : "false")
+ .arg(do_fwd ? "true" : "false");
- lease->preferred_lft_ = subnet->getPreferred();
- lease->valid_lft_ = subnet->getValid();
- lease->t1_ = subnet->getT1();
- lease->t2_ = subnet->getT2();
- lease->cltt_ = time(NULL);
- lease->hostname_ = hostname;
- lease->fqdn_fwd_ = do_fwd;
- lease->fqdn_rev_ = do_rev;
+ createRemovalNameChangeRequest(lease);
+ }
- // Create empty IA_NA option with IAID matching the request.
- boost::shared_ptr<Option6IA> ia_rsp(new Option6IA(D6O_IA_NA, ia->getIAID()));
+ lease->preferred_lft_ = subnet->getPreferred();
+ lease->valid_lft_ = subnet->getValid();
+ lease->t1_ = subnet->getT1();
+ lease->t2_ = subnet->getT2();
+ lease->cltt_ = time(NULL);
+ lease->hostname_ = hostname;
+ lease->fqdn_fwd_ = do_fwd;
+ lease->fqdn_rev_ = do_rev;
- ia_rsp->setT1(subnet->getT1());
- ia_rsp->setT2(subnet->getT2());
+ ia_rsp->setT1(subnet->getT1());
+ ia_rsp->setT2(subnet->getT2());
- boost::shared_ptr<Option6IAAddr> addr(new Option6IAAddr(D6O_IAADDR,
- lease->addr_, lease->preferred_lft_,
- lease->valid_lft_));
- ia_rsp->addOption(addr);
+ Option6IAAddrPtr addr(new Option6IAAddr(D6O_IAADDR, lease->addr_,
+ lease->preferred_lft_,
+ lease->valid_lft_));
+ ia_rsp->addOption(addr);
+ }
bool skip = false;
- // Execute all callouts registered for packet6_send
- if (HooksManager::calloutsPresent(Hooks.hook_index_lease6_renew_)) {
+ // Get the callouts specific for the processed message and execute them.
+ int hook_point = query->getType() == DHCPV6_RENEW ?
+ Hooks.hook_index_lease6_renew_ : Hooks.hook_index_lease6_rebind_;
+ if (HooksManager::calloutsPresent(hook_point)) {
CalloutHandlePtr callout_handle = getCalloutHandle(query);
// Delete all previous arguments