diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 1c8ffdcc43..e6ab1be386 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -893,26 +893,7 @@ Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer, // Get the list of options that client requested. const std::vector& requested_opts = option_oro->getValues(); - if (co_list.empty()) { - // If there are no options configured, we at least have to check if - // the client has requested PD exclude, which is configured as - // part of the pool configuration. - ctx.pd_exclude_requested_ = (std::find(requested_opts.begin(), - requested_opts.end(), - D6O_PD_EXCLUDE) != - requested_opts.end()); - return; - } - BOOST_FOREACH(uint16_t opt, requested_opts) { - // Prefix Exclude option requires special handling, as it can - // be configured as part of the pool configuration. - if (opt == D6O_PD_EXCLUDE) { - ctx.pd_exclude_requested_ = true; - // Prefix Exclude can only be included in the IA Prefix option - // of IA_PD. Thus there is nothing more to do here. - continue; - } // Iterate on the configured option list for (CfgOptionList::const_iterator copts = co_list.begin(); copts != co_list.end(); ++copts) { @@ -1576,6 +1557,8 @@ Dhcpv6Srv::assignIA_PD(const Pkt6Ptr& query, const Pkt6Ptr& answer, ia_rsp->setT1(subnet->getT1()); ia_rsp->setT2(subnet->getT2()); + const bool pd_exclude_requested = requestedInORO(query, D6O_PD_EXCLUDE); + for (Lease6Collection::iterator l = leases.begin(); l != leases.end(); ++l) { @@ -1594,14 +1577,12 @@ Dhcpv6Srv::assignIA_PD(const Pkt6Ptr& query, const Pkt6Ptr& answer, (*l)->valid_lft_)); ia_rsp->addOption(addr); - if (ctx.pd_exclude_requested_) { + if (pd_exclude_requested) { // PD exclude option has been requested via ORO, thus we need to // include it if the pool configuration specifies this option. Pool6Ptr pool = boost::dynamic_pointer_cast< Pool6>(subnet->getPool(Lease::TYPE_PD, (*l)->addr_)); if (pool && pool->getExcludedPrefixLength() > 0) { - std::cout << pool->getExcludedPrefix() << "/" - << (unsigned)pool->getExcludedPrefixLength() << std::endl; OptionPtr opt(new Option6PDExclude((*l)->addr_, (*l)->prefixlen_, pool->getExcludedPrefix(), @@ -1877,6 +1858,8 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query, // into temporary container. AllocEngine::HintContainer hints = ctx.currentIA().hints_; + const bool pd_exclude_requested = requestedInORO(query, D6O_PD_EXCLUDE); + // For all the leases we have now, add the IAPPREFIX with non-zero lifetimes for (Lease6Collection::const_iterator l = leases.begin(); l != leases.end(); ++l) { @@ -1885,7 +1868,8 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query, (*l)->preferred_lft_, (*l)->valid_lft_)); ia_rsp->addOption(prf); - if (ctx.pd_exclude_requested_) { + + if (pd_exclude_requested) { // PD exclude option has been requested via ORO, thus we need to // include it if the pool configuration specifies this option. Pool6Ptr pool = boost::dynamic_pointer_cast< @@ -3288,5 +3272,19 @@ int Dhcpv6Srv::getHookIndexBuffer6Send() { return (Hooks.hook_index_buffer6_send_); } +bool +Dhcpv6Srv::requestedInORO(const Pkt6Ptr& query, const uint16_t code) const { + OptionUint16ArrayPtr oro = + boost::dynamic_pointer_cast(query->getOption(D6O_ORO)); + + if (oro) { + const std::vector& codes = oro->getValues(); + return (std::find(codes.begin(), codes.end(), code) != codes.end()); + } + + return (false); +} + + }; }; diff --git a/src/bin/dhcp6/dhcp6_srv.h b/src/bin/dhcp6/dhcp6_srv.h index 63e0397ec2..7c3f907ac0 100644 --- a/src/bin/dhcp6/dhcp6_srv.h +++ b/src/bin/dhcp6/dhcp6_srv.h @@ -805,6 +805,15 @@ private: /// @param query packet received static void processStatsReceived(const Pkt6Ptr& query); + /// @brief Checks if the specified option code has been requested using + /// the Option Request option. + /// + /// @param query Pointer to the client's query. + /// @parma code Option code. + /// + /// @return true if option has been requested in the ORO. + bool requestedInORO(const Pkt6Ptr& query, const uint16_t code) const; + /// UDP port number on which server listens. uint16_t port_; diff --git a/src/bin/dhcp6/tests/renew_unittest.cc b/src/bin/dhcp6/tests/renew_unittest.cc index 07324f2433..c61066fcd8 100644 --- a/src/bin/dhcp6/tests/renew_unittest.cc +++ b/src/bin/dhcp6/tests/renew_unittest.cc @@ -218,7 +218,7 @@ const char* RENEW_CONFIGS[] = { " \"interface-id\": \"\"," " \"interface\": \"eth0\"" " } ]," - "\"valid-lifetime\": 4000 } + "\"valid-lifetime\": 4000 }" }; /// @brief Test fixture class for testing Renew. @@ -352,7 +352,7 @@ TEST_F(RenewTest, renewWithExcludedPrefix) { ASSERT_FALSE(option); // Reconfigure the server to use the prefix pool with excluded prefix. - configure(RENEW_CONFIGS[4], *client.getServer()); + configure(RENEW_CONFIGS[5], *client.getServer()); // Send Renew message to the server, including IA_NA and IA_PD. ASSERT_NO_THROW(client.doRenew()); diff --git a/src/bin/dhcp6/tests/sarr_unittest.cc b/src/bin/dhcp6/tests/sarr_unittest.cc index 1a085f802f..d053bd3b2a 100644 --- a/src/bin/dhcp6/tests/sarr_unittest.cc +++ b/src/bin/dhcp6/tests/sarr_unittest.cc @@ -339,7 +339,7 @@ TEST_F(SARRTest, directClientExcludedPrefix) { // Configure client to request IA_PD. client.requestPrefix(); client.requestOption(D6O_PD_EXCLUDE); - configure(CONFIGS[2], *client.getServer()); + configure(CONFIGS[3], *client.getServer()); // Make sure we ended-up having expected number of subnets configured. const Subnet6Collection* subnets = CfgMgr::instance().getCurrentCfg()-> getCfgSubnets6()->getAll(); diff --git a/src/lib/dhcpsrv/alloc_engine.cc b/src/lib/dhcpsrv/alloc_engine.cc index c78574efc7..c941d125b5 100644 --- a/src/lib/dhcpsrv/alloc_engine.cc +++ b/src/lib/dhcpsrv/alloc_engine.cc @@ -350,7 +350,7 @@ AllocEngine::ClientContext6::ClientContext6(const Subnet6Ptr& subnet, duid_(duid), hwaddr_(), host_identifiers_(), host_(), fwd_dns_update_(fwd_dns), rev_dns_update_(rev_dns), hostname_(hostname), callout_handle_(callout_handle), - allocated_resources_(), ias_(), pd_exclude_requested_(false) { + allocated_resources_(), ias_() { // Initialize host identifiers. if (duid) { diff --git a/src/lib/dhcpsrv/alloc_engine.h b/src/lib/dhcpsrv/alloc_engine.h index 61958fab4f..c28775666c 100644 --- a/src/lib/dhcpsrv/alloc_engine.h +++ b/src/lib/dhcpsrv/alloc_engine.h @@ -397,10 +397,6 @@ public: /// @brief Container holding IA specific contexts. std::vector ias_; - /// @brief Indicates if PD exclude option has been requested by a - /// client. - bool pd_exclude_requested_; - /// @brief Convenience method adding allocated prefix or address. /// /// @param prefix Prefix or address. diff --git a/src/lib/dhcpsrv/dhcp4o6_ipc.cc b/src/lib/dhcpsrv/dhcp4o6_ipc.cc index 063e808894..86dfafc378 100644 --- a/src/lib/dhcpsrv/dhcp4o6_ipc.cc +++ b/src/lib/dhcpsrv/dhcp4o6_ipc.cc @@ -71,7 +71,7 @@ int Dhcp4o6IpcBase::open(uint16_t port, EndpointType endpoint_type) { } // We'll connect to the loopback address so bind to it too. local6.sin6_addr.s6_addr[15] = 1; - if (bind(sock, (struct sockaddr *)&local6, sizeof(local6)) < 0) { + if (::bind(sock, (struct sockaddr *)&local6, sizeof(local6)) < 0) { ::close(sock); isc_throw(Dhcp4o6IpcError, "Failed to bind DHCP4o6 socket."); } diff --git a/src/lib/dhcpsrv/pgsql_host_data_source.cc b/src/lib/dhcpsrv/pgsql_host_data_source.cc index b1dce8033b..12a3cc73f8 100644 --- a/src/lib/dhcpsrv/pgsql_host_data_source.cc +++ b/src/lib/dhcpsrv/pgsql_host_data_source.cc @@ -525,11 +525,7 @@ private: // If the option space is a standard DHCPv4 or DHCPv6 option space, // this is most likely a standard option, for which we have a // definition created within libdhcp++. - OptionDefinitionPtr def; - if ((space == DHCP4_OPTION_SPACE) || - (space == DHCP6_OPTION_SPACE)) { - def = LibDHCP::getOptionDef(universe_, code); - } + OptionDefinitionPtr def = LibDHCP::getOptionDef(space, code); // Otherwise, we may check if this an option encapsulated within the // vendor space.