From: Marcin Siodelski Date: Wed, 12 Mar 2014 08:41:05 +0000 (+0100) Subject: [3232] Merge branch 'master' into trac3232 X-Git-Tag: kea-eng-20140313~11^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=58de1eed517805118a5d883caf88a2fe951d0dc9;p=thirdparty%2Fkea.git [3232] Merge branch 'master' into trac3232 Conflicts: src/bin/dhcp6/dhcp6_messages.mes src/bin/dhcp6/dhcp6_srv.cc src/bin/dhcp6/dhcp6_srv.h src/bin/dhcp6/tests/dhcp6_test_utils.cc --- 58de1eed517805118a5d883caf88a2fe951d0dc9 diff --cc src/bin/dhcp6/dhcp6_messages.mes index 990ca087b8,e1c7b4a49e..811104507b --- a/src/bin/dhcp6/dhcp6_messages.mes +++ b/src/bin/dhcp6/dhcp6_messages.mes @@@ -110,55 -101,25 +101,74 @@@ that the DNS Update has been performed database has invalid format and can't be transformed to the canonical on-wire format. + % DHCP6_DDNS_REQUEST_SEND_FAILED failed sending a request to b10-dhcp-ddns, error: %1, ncr: %2 + This error message indicates that IPv6 DHCP server failed to send a DDNS + update reqeust to the DHCP-DDNS server. This is most likely a configuration or + networking error. + + % DHCP6_DDNS_SEND_FQDN sending DHCPv6 Client FQDN Option to the client: %1 + This debug message is logged when server includes an DHCPv6 Client FQDN Option + in its response to the client. + + % DHCP6_DEACTIVATE_INTERFACE deactivate interface %1 + This message is printed when DHCPv6 server disables an interface from being + used to receive DHCPv6 traffic. Sockets on this interface will not be opened + by the Interface Manager until interface is enabled. + + % DHCP6_HOOKS_LIBS_RELOAD_FAIL reload of hooks libraries failed + A "libreload" command was issued to reload the hooks libraries but for + some reason the reload failed. Other error messages issued from the + hooks framework will indicate the nature of the problem. + +% DHCP6_EXTEND_LEASE_SUBNET_SELECTED the %1 subnet was selected for client extending its lease +This is a debug message informing that a given subnet was selected. It will +be used for extending lifetime of the lease. This is one of the early steps +in the processing of incoming client message. + +% DHCP6_EXTEND_LEASE_SUBNET_SELECT_FAILED failed to select a subnet for received %1: src=%2 type=%3 +This warning message is output when a Renew or Rebind was received from a +subnet for which the DHCPv6 server has not been configured. The cause is +most likely due to a misconfiguration of the server. The packet processing +will continue, but the response will only contain generic configuration +parameters and no addresses or prefixes. + +% DHCP6_EXTEND_NA_UNKNOWN received unknown IA_NA from client (duid=%1, iaid=%2) in subnet %3 +This warning message is printed when client attempts to extend the lease +for the address (in the IA_NA option) but no such lease is known by the server. +It typically means that client has attempted to use its lease past its +lifetime: causes of this include a adjustment of the client's date/time +setting or poor support on the client for sleep/recovery. A properly +implemented client will recover from such a situation by restarting the +lease allocation process after receiving a negative reply from the server. + +An alternative cause could be that the server has lost its database +recently and does not recognize its well-behaving clients. This is more +probable if you see many such messages. Clients will recover from this, +but they will most likely get a different IP addresses and experience +a brief service interruption. + +% DHCP6_EXTEND_NA_UNKNOWN_SUBNET %1 message received from client on unknown subnet (duid=%2, iaid=%3) +A warning message indicating that a client is attempting to extend lease lifetime +for the address, but the server does not have any information about the subnet this +client belongs to. This may mean that faulty the mobile client changed its location +and is trying to renew its old address (client is supposed to send confirm, not rewew +in such cases, according to RFC3315) or the server configuration has changed and +information about existing subnet was removed. Note that in a sense this is worse +case of DHCP6_EXTEND_NA_UNKNOWN, as not only the lease is unknown, but also the subnet +is. Depending on the reasons of this condition, it may or may not correct on its own. + +% DHCP6_EXTEND_PD_NO_BINDING client sent a %1 message to extend lifetimes of prefixes for an unknown binding: duid=%2, iaid=%3, subnet=%4 +This warning message is logged when a client attempts to extend the lifetime of the +prefix it is using, but the server was unable to find the binding to which +this lease belongs. This error condition has different implications for the +Renew and Rebind messages. For the former, the server will respond with NoBinding +status code. For the latter, the server will discard the message. + +% DHCP6_EXTEND_PD_UNKNOWN_SUBNET %1 message received from client on unknown subnet (duid=%2, iaid=%3) +A warning message indicating that a client is attempting to extend lease lifetime +for the prefix, but the server doesn't have any information about the subnet this +client belongs to. + % DHCP6_HOOK_BUFFER_RCVD_SKIP received DHCPv6 buffer was dropped because a callout set the skip flag This debug message is printed when a callout installed on buffer6_receive hook point set the skip flag. For this particular hook point, the @@@ -171,14 -132,6 +181,12 @@@ setting of the flag by a callout instru Server completed all the processing (e.g. may have assigned, updated or released leases), but the response will not be send to the client. +% DHCP6_HOOK_LEASE6_EXTEND_SKIP DHCPv6 lease lifetime was not extended because a callout set the skip flag for message %1 - This debug message is printed when a callout installed on lease6_renew +or lease6_rebind hook point set the skip flag. For this particular hook +point, the setting of the flag by a callout instructs the server to not +extend the lifetime for a lease. If client requested renewal of multiples +leases (by sending multiple IA options), the server will skip the renewal +of the one in question and will proceed with other renewals as usual. - % DHCP6_HOOK_LEASE6_RELEASE_NA_SKIP DHCPv6 address lease was not released because a callout set the skip flag This debug message is printed when a callout installed on the lease6_release hook point set the skip flag. For this particular hook @@@ -439,12 -401,16 +456,6 @@@ that does belong to it, but the addres IA (identity association) container. This probably means that the client's support for multiple prefixes is flawed. - % DHCP6_RELEASE_MISSING_CLIENTID client (address=%1) sent RELEASE message without mandatory client-id - This warning message indicates that client sent RELEASE message without - mandatory client-id option. This is most likely caused by a buggy client - (or a relay that malformed forwarded message). This request will not be - processed and a response with error status code will be sent back. -% DHCP6_RENEW_UNKNOWN_SUBNET RENEW message received from client on unknown subnet (duid=%1, iaid=%2) -A warning message indicating that a client is attempting to renew his lease, -but the server does not have any information about the subnet this client belongs -to. This may mean that faulty the mobile client changed its location and is trying to -renew its old address (client is supposed to send confirm, not rewew in such cases, -according to RFC3315) or the server configuration has changed and information about -existing subnet was removed. Note that in a sense this is worse case of DHCP6_UNKNOWN_RENEW, -as not only the lease is unknown, but also the subnet is. Depending on the reasons -of this condition, it may or may not correct on its own. -- % DHCP6_REQUIRED_OPTIONS_CHECK_FAIL %1 message received from %2 failed the following check: %3 This message indicates that received DHCPv6 packet is invalid. This may be due to a number of reasons, e.g. the mandatory client-id option is missing, diff --cc src/bin/dhcp6/dhcp6_srv.cc index 7d91bf815b,dc92ee85ea..aac0ff6645 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@@ -1574,93 -1452,70 +1487,93 @@@ 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) { + 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; + + } 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 + // 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; + if (fqdn->getFlag(Option6ClientFqdn::FLAG_S)) { + do_fwd = true; + do_rev = true; - } else if (!fqdn->getFlag(Option6ClientFqdn::FLAG_N)) { - do_rev = true; + } } - } - 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"); + std::string hostname; + if (do_fwd || do_rev) { + hostname = fqdn->getDomainName(); + } - createRemovalNameChangeRequest(lease); - } + // 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 diff --cc src/bin/dhcp6/dhcp6_srv.h index e3cedfe52e,e0d4791996..24655291d0 --- a/src/bin/dhcp6/dhcp6_srv.h +++ b/src/bin/dhcp6/dhcp6_srv.h @@@ -469,28 -455,15 +497,17 @@@ protected /// records will be performed. void createRemovalNameChangeRequest(const Lease6Ptr& lease); - /// @brief Sends all outstanding NameChangeRequests to bind10-d2 module. - /// - /// The purpose of this function is to pick all outstanding - /// NameChangeRequests from the FIFO queue and send them to b10-dhcp-ddns - /// module. - /// - /// @todo Currently this function simply removes all requests from the - /// queue but doesn't send them anywhere. In the future, the - /// NameChangeSender will be used to deliver requests to the other module. - void sendNameChangeRequests(); - - /// @brief Attempts to renew received addresses + /// @brief Attempts to extend the lifetime of IAs. + /// + /// This function is called when a client sends Renew or Rebind message. + /// It iterates through received IA options and attempts to extend + /// corresponding lease lifetimes. Internally, it calls + /// @c Dhcpv6Srv::extendIA_NA and @c Dhcpv6Srv::extendIA_PD to extend + /// the lifetime of IA_NA and IA_PD leases accordingly. /// - /// It iterates through received IA_NA options and attempts to renew - /// received addresses. If no such leases are found, proper status - /// code is added to reply message. Renewed addresses are added - /// as IA_NA/IAADDR to reply packet. - /// @param renew client's message asking for renew + /// @param query client's Renew or Rebind message /// @param reply server's response - void renewLeases(const Pkt6Ptr& renew, Pkt6Ptr& reply); + void extendLeases(const Pkt6Ptr& query, Pkt6Ptr& reply); /// @brief Attempts to release received addresses /// diff --cc src/bin/dhcp6/tests/dhcp6_test_utils.cc index 451102e00a,fb05067b91..a318a70940 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.cc +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.cc @@@ -133,17 -147,12 +159,18 @@@ Dhcpv6SrvTest::checkPdLease(const DuidP Pkt6Ptr Dhcpv6SrvTest::createMessage(uint8_t message_type, Lease::Type lease_type, const IOAddress& addr, const uint8_t prefix_len, - uint32_t iaid) { - // Let's create a RENEW + const uint32_t iaid) { Pkt6Ptr msg = Pkt6Ptr(new Pkt6(message_type, 1234)); msg->setRemoteAddr(IOAddress("fe80::abcd")); + msg->setIface("eth0"); + msg->addOption(createIA(lease_type, addr, prefix_len, iaid)); + return (msg); +} +Option6IAPtr +Dhcpv6SrvTest::createIA(isc::dhcp::Lease::Type lease_type, + const isc::asiolink::IOAddress& addr, + const uint8_t prefix_len, const uint32_t iaid) { uint16_t code; OptionPtr subopt; switch (lease_type) { diff --cc src/bin/dhcp6/tests/dhcp6_test_utils.h index 05942689b7,b68f7b5bbe..a006e18584 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.h +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.h @@@ -110,8 -109,8 +110,9 @@@ public using Dhcpv6Srv::loadServerID; using Dhcpv6Srv::writeServerID; using Dhcpv6Srv::unpackOptions; + using Dhcpv6Srv::shutdown_; using Dhcpv6Srv::name_change_reqs_; + using Dhcpv6Srv::VENDOR_CLASS_PREFIX; /// @brief packets we pretend to receive ///