From: Thomas Markwalder Date: Thu, 13 Mar 2014 17:33:15 +0000 (-0400) Subject: [master] Merge branch 'trac3352' X-Git-Tag: kea-eng-20140313~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b1a0f405463723d539b2e6ed2dcdd692d7796b88;p=thirdparty%2Fkea.git [master] Merge branch 'trac3352' Resolved Conflicts: src/bin/dhcp6/dhcp6_srv.cc --- b1a0f405463723d539b2e6ed2dcdd692d7796b88 diff --cc src/bin/dhcp6/dhcp6_srv.cc index aac0ff6645,a07bec81ea..cc99ab375a --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@@ -1487,93 -1458,66 +1493,90 @@@ Dhcpv6Srv::extendIA_NA(const Subnet6Ptr 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 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 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