21#include <boost/pointer_cast.hpp>
40 return (first->cltt_ > second->cltt_);
51 Pkt4Ptr query = boost::dynamic_pointer_cast<Pkt4>(base_query);
58 IOAddress requester_ip = query->getGiaddr();
62 static_cast<int64_t
>(1));
69 static_cast<int64_t
>(1));
79 << requester_ip.
toText() <<
", unknown server-id: "
80 << (client_server_id ? client_server_id->toText() :
"malformed"));
87 uint8_t query_mask = (!ciaddr.
isV4Zero() ? 1 : 0);
91 query_mask |= (hwaddr->hwaddr_.size() ? 2 : 0);
96 client_id.reset(
new ClientId(opt->getData()));
105 switch (query_mask) {
122 static_cast<int64_t
>(1));
124 <<
"ciaddr: [" << ciaddr
125 <<
"] HWAddr: [" << hwaddr->
toText()
126 <<
"] Client id: [" << (client_id ? client_id->toText() :
"")
144 leases.push_back(lease);
157 for (
auto const& subnet : *subnets) {
188 if (!found_leases.empty()) {
189 for (
auto const& lease : found_leases) {
191 active_leases.push_back(lease);
195 std::sort(active_leases.begin(), active_leases.end(), cltt_descending);
198 return (active_leases);
208 switch(response_type) {
217 response->setCiaddr(query->getCiaddr());
218 response->setHWAddr(query->getHWAddr());
221 response->addOption(opt);
232 if (leases.size() == 0) {
240 response->setCiaddr(newest->addr_);
241 if (newest->hwaddr_) {
242 response->setHWAddr(newest->hwaddr_);
264 Pkt4Ptr response(
new Pkt4(response_type, query->getTransid()));
265 response->setGiaddr(query->getGiaddr());
271 response->setRemoteAddr(query->getGiaddr());
272 response->setRemotePort(DHCP4_SERVER_PORT);
274 HWAddrPtr dst_hw_addr = query->getRemoteHWAddr();
276 response->setRemoteHWAddr(dst_hw_addr);
280 IOAddress local_addr = query->getLocalAddr();
285 response->setLocalAddr(local_addr);
286 response->setLocalPort(query->getLocalPort());
287 response->setIface(query->getIface());
288 response->setIndex(query->getIndex());
290 HWAddrPtr src_hw_addr = query->getLocalHWAddr();
292 response->setLocalHWAddr(src_hw_addr);
297 if (client_server_id) {
298 response->addOption(client_server_id);
308 for (
auto const& lease : leases) {
309 if (lease->addr_ != response->getCiaddr()) {
310 associates->addAddress(lease->addr_);
316 response->addOption(associates);
328 ->getCfgSubnets4()->getSubnet(lease->subnet_id_);
334 if (lease->client_id_) {
336 lease->client_id_->getClientId()));
337 response->addOption(cid_opt);
356 time_t now = time(0);
360 if (now > lease->cltt_) {
361 elapsed = now - lease->cltt_;
369 response->addOption(opt);
375 response->addOption(opt);
380 time_t adjusted_lft = lease->valid_lft_ - elapsed;
384 response->addOption(opt);
391 if (!subnet->getT2().unspecified()) {
392 t2_time = subnet->getT2();
393 }
else if (subnet->getCalculateTeeTimes()) {
395 t2_time =
static_cast<time_t
>(round(subnet->getT2Percent()
396 * (lease->valid_lft_)));
404 time_t timer_ceiling = adjusted_lft;
405 if (t2_time > 0 && t2_time < timer_ceiling) {
407 response->addOption(t2);
409 timer_ceiling = t2_time;
414 if (!subnet->getT1().unspecified()) {
415 t1_time = subnet->getT1();
416 }
else if (subnet->getCalculateTeeTimes()) {
418 t1_time =
static_cast<time_t
>(round(subnet->getT1Percent()
419 * (lease->valid_lft_)));
427 if (t1_time > 0 && t1_time < timer_ceiling) {
429 response->addOption(t1);
436 if (lease->getContext()) {
445 if (!extended_info) {
449 ConstElementPtr relay_agent_info = extended_info->get(
"relay-agent-info");
450 if (!relay_agent_info) {
458 relay_agent_info = relay_agent_info->get(
"sub-options");
459 if (!relay_agent_info) {
465 std::vector<uint8_t> opt_data;
470 response->addOption(rai);
471 }
catch (
const std::exception& ex) {
478 std::stringstream label;
481 label <<
"type: " << packet->getName()
482 <<
", giaddr: " << packet->getGiaddr().toText()
483 <<
", transid: " << packet->getTransid()
484 <<
", ciaddr: " << packet->getCiaddr().toText();
487 label <<
", hwaddr: " << (hwaddr ? hwaddr->toText() :
"none");
491 label <<
", cid: none";
494 ClientId client_id(client_opt->getData());
495 label <<
", cid: " << client_id.
toText();
497 label <<
", cid: (malformed)";
500 }
catch (
const std::exception& ex) {
502 label <<
"label error" << ex.what();
505 return (label.str());
513 }
catch (
const std::exception& ex) {
523 .arg(response->getRemoteAddr())
524 .arg(response->getRemotePort());
527 switch (response->getType()) {
530 static_cast<int64_t
>(1));
534 static_cast<int64_t
>(1));
538 static_cast<int64_t
>(1));
545 }
catch (
const std::exception& ex) {
548 .arg(response->getIface())
549 .arg(response->getRemoteAddr())
550 .arg(response->getRemotePort())
560 if (!server_id_opt) {
568 boost::dynamic_pointer_cast<OptionCustom>(server_id_opt);
571 if (!option_custom) {
573 static_cast<int64_t
>(1));
577 if (option_custom->getDataFieldsNum() != 1) {
579 static_cast<int64_t
>(1));
584 IOAddress client_server_id = option_custom->readAddress();
585 if (!client_server_id.
isV4() ||
588 static_cast<int64_t
>(1));
602 if (cfg_subnets->hasSubnetWithServerId(client_server_id)) {
609 if (cfg_networks->hasNetworkWithServerId(client_server_id)) {
615 for (
auto const& cclass : classes) {
618 getClientClassDictionary()->findClass(cclass);
623 if (ccdef->getCfgOption()->empty()) {
628 OptionCustomPtr context_opt_server_id = boost::dynamic_pointer_cast<OptionCustom>
630 if (context_opt_server_id && (context_opt_server_id->readAddress() == client_server_id)) {
637 OptionCustomPtr cfg_server_id = boost::dynamic_pointer_cast<OptionCustom>
640 if (cfg_server_id && (cfg_server_id->readAddress() == client_server_id)) {
646 static_cast<int64_t
>(1));
658 for (
auto const& cfg_options : co_list) {
662 response->addOption(server_id_desc.
option_);
670 server_id->writeAddress(response->getLocalAddr());
671 response->addOption(server_id);
693 if (pool && !pool->getCfgOption()->empty()) {
694 co_list.push_back(pool->getCfgOption());
698 if (!subnet->getCfgOption()->empty()) {
699 co_list.push_back(subnet->getCfgOption());
704 subnet->getSharedNetwork(network);
705 if (network && !network->getCfgOption()->empty()) {
706 co_list.push_back(network->getCfgOption());
711 for (
auto const& cclass : classes) {
714 getClientClassDictionary()->findClass(cclass);
720 if (ccdef->getCfgOption()->empty()) {
725 co_list.push_back(ccdef->getCfgOption());
743 upgraded = lease_mgr.upgradeExtendedInfo4(page_size);
744 }
catch (
const std::exception& ex) {
752 std::ostringstream msg;
753 msg <<
"Upgraded " << upgraded <<
" lease";
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown when an unexpected error condition occurs.
The IOAddress class represents an IP addresses (version agnostic).
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
bool isV4Zero() const
Convenience function to check if it is an IPv4 zero address.
std::string toText() const
Convert the address to a string.
bool isV4() const
Convenience function to check for an IPv4 address.
bool isV4Bcast() const
Convenience function to check if it is an IPv4 broadcast address.
static CfgMgr & instance()
returns a single instance of Configuration Manager
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Container for storing client class names.
Holds Client identifier or client IPv4 address.
std::string toText() const
Returns textual representation of the identifier (e.g.
static IfaceMgr & instance()
IfaceMgr is a singleton class.
bool send(const Pkt6Ptr &pkt)
Sends an IPv6 packet.
uint16_t getSocket(const isc::dhcp::Pkt6Ptr &pkt)
Return most suitable socket for transmitting specified IPv6 packet.
static TrackingLeaseMgr & instance()
Return current lease manager.
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress &addr) const =0
Returns an IPv4 lease for specified IPv4 address.
Wraps value holding size of the page with leases.
static const OptionDefinition & DHO_DHCP_SERVER_IDENTIFIER_DEF()
Get definition of DHO_DHCP_SERVER_IDENTIFIER option.
DHCPv4 Option class for handling list of IPv4 addresses.
Option with defined data fields represented as buffers that can be accessed using data field index.
Base class representing a DHCP option definition.
OptionPtr option_
Option instance.
Represents DHCPv4 packet.
Per-packet callout handle.
void setArgument(const std::string &name, T value)
Set argument.
static dhcp::DHCPMessageType queryByIpAddress(const asiolink::IOAddress &ciaddr, dhcp::Lease4Collection &leases)
Queries for an active lease matching an ip address.
static void addOptions(const dhcp::Pkt4Ptr &query, dhcp::Pkt4Ptr response, const dhcp::Lease4Ptr &lease)
Adds options to a query response.
static int upgradeHandler(hooks::CalloutHandle &handle)
Upgrade extended information.
static void sendResponse(const dhcp::Pkt4Ptr &response)
Packs and sends a query response.
static void addLeaseTimes(dhcp::Pkt4Ptr response, const dhcp::Lease4Ptr &lease, const dhcp::Subnet4Ptr &subnet)
Adds life time, T1, and T2 options to a query response.
LeaseQueryImpl4(const data::ConstElementPtr config)
Constructor.
virtual void processQuery(isc::dhcp::PktPtr base_query, bool &invalid) const
Processes a single DHCPv4 client Lease Query.
static void addAssociatedLeases(dhcp::Pkt4Ptr response, const dhcp::Lease4Collection &leases)
Adds associated leases to a query response.
static std::string leaseQueryLabel(const dhcp::Pkt4Ptr &packet)
Convenience method for generating per packet logging info.
static dhcp::Lease4Collection winnowLeases(const dhcp::Lease4Collection &leases)
Creates a list of active leases from a list of leases.
static bool acceptServerId(const dhcp::Pkt4Ptr &query, dhcp::OptionPtr &server_id_opt)
Validates dhcp-server-identifier option in the inbound query (if one).
static dhcp::DHCPMessageType queryByHWAddr(const dhcp::HWAddrPtr &hwaddr, dhcp::Lease4Collection &leases)
Queries LeaseMgr for active leases matching a HW address.
static void buildCfgOptionList(dhcp::CfgOptionList &co_list, const dhcp::Pkt4Ptr &query, const dhcp::Lease4Ptr &lease=dhcp::Lease4Ptr(), const dhcp::Subnet4Ptr &subnet=dhcp::Subnet4Ptr())
Constructs a list of configured option sets for a given lease and it's subnet.
static dhcp::DHCPMessageType queryByClientId(const dhcp::ClientIdPtr &client_id, dhcp::Lease4Collection &leases)
Queries LeaseMgr for active leases matching a client.
static void appendServerId(dhcp::Pkt4Ptr &response, dhcp::CfgOptionList &co_list)
Adds dhcp-server-identifier option (54) to the response.
static void addRelayAgentInfo(dhcp::Pkt4Ptr response, const dhcp::Lease4Ptr &lease)
Adds relay-agent-info option to a query response.
static dhcp::Pkt4Ptr initResponse(dhcp::DHCPMessageType response_type, const dhcp::Pkt4Ptr &query)
Creates the initial query response.
static dhcp::Pkt4Ptr buildResponse(dhcp::DHCPMessageType response_type, const dhcp::Pkt4Ptr &query, const dhcp::Lease4Collection &leases)
Creates a lease query response packet.
LeaseQueryImpl(uint16_t family, const isc::data::ConstElementPtr config)
Constructor.
bool isRequester(const isc::asiolink::IOAddress &address) const
Checks if the given address belongs to a valid requester.
static size_t PageSize
Page size to commands.
static StatsMgr & instance()
Statistics Manager accessor method.
RAII class creating a critical section.
This file contains several functions and constants that are used for handling commands and responses ...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
OptionInt< uint32_t > OptionUint32
boost::shared_ptr< OptionUint32 > OptionUint32Ptr
void addValue(const std::string &name, const int64_t value)
Records incremental integer observation.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
ConstElementPtr createAnswer()
Creates a standard config/command level success answer message (i.e.
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
boost::shared_ptr< const Element > ConstElementPtr
boost::shared_ptr< isc::dhcp::Pkt > PktPtr
A pointer to either Pkt4 or Pkt6 packet.
boost::shared_ptr< Subnet4 > Subnet4Ptr
A pointer to a Subnet4 object.
@ DHO_DHCP_REBINDING_TIME
@ DHO_DHCP_SERVER_IDENTIFIER
@ DHO_DHCP_CLIENT_IDENTIFIER
@ DHO_CLIENT_LAST_TRANSACTION_TIME
boost::shared_ptr< OptionCustom > OptionCustomPtr
A pointer to the OptionCustom object.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
boost::shared_ptr< ClientClassDef > ClientClassDefPtr
a pointer to an ClientClassDef
boost::shared_ptr< SrvConfig > SrvConfigPtr
Non-const pointer to the SrvConfig.
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
boost::multi_index_container< Subnet4Ptr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID, &Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string, &Subnet::toText > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetServerIdIndexTag >, boost::multi_index::const_mem_fun< Network4, asiolink::IOAddress, &Network4::getServerId > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetModificationTimeIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime, &data::BaseStampedElement::getModificationTime > > > > Subnet4Collection
A collection of Subnet4 objects.
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
boost::shared_ptr< const CfgSubnets4 > ConstCfgSubnets4Ptr
Const pointer.
boost::shared_ptr< CfgSharedNetworks4 > CfgSharedNetworks4Ptr
Pointer to the configuration of IPv4 shared networks.
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
boost::shared_ptr< Option4AddrLst > Option4AddrLstPtr
A pointer to the Option4AddrLst object.
boost::shared_ptr< Option > OptionPtr
std::list< ConstCfgOptionPtr > CfgOptionList
Const pointer list.
const isc::log::MessageID DHCP4_LEASE_QUERY_PACKET_PACK_FAILED
const isc::log::MessageID DHCP4_LEASE_QUERY_SEND_FAILED
const isc::log::MessageID DHCP4_LEASE_QUERY_RESPONSE_SENT
isc::log::Logger lease_query_logger("lease-query-hooks")
const int DBGLVL_TRACE_BASIC
Trace basic operations.
void decodeFormattedHexString(const string &hex_string, vector< uint8_t > &binary)
Converts a formatted string of hexadecimal digits into a vector.
Defines the logger used by the top-level component of kea-lfc.
#define DHCP4_OPTION_SPACE
global std option spaces
static data::ElementPtr toElement(data::ConstElementPtr map)
Copy an Element map.
Hardware type that represents information from DHCPv4 packet.
static const uint32_t INFINITY_LFT
Infinity (means static, i.e. never expire).
static constexpr uint32_t STATE_DEFAULT
A lease in the default state.