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);
90 query_mask |= ((hwaddr->htype_ || hwaddr->hwaddr_.size()) ? 2 : 0);
95 client_id.reset(
new ClientId(opt->getData()));
104 switch (query_mask) {
121 static_cast<int64_t
>(1));
123 <<
"ciaddr: [" << ciaddr
124 <<
"] HWAddr: [" << hwaddr->
toText()
125 <<
"] Client id: [" << (client_id ? client_id->toText() :
"")
143 leases.push_back(lease);
156 for (
auto const& subnet : *subnets) {
187 if (!found_leases.empty()) {
188 for (
auto const& lease : found_leases) {
190 active_leases.push_back(lease);
194 std::sort(active_leases.begin(), active_leases.end(), cltt_descending);
197 return (active_leases);
207 switch(response_type) {
216 response->setCiaddr(query->getCiaddr());
217 response->setHWAddr(query->getHWAddr());
220 response->addOption(opt);
231 if (leases.size() == 0) {
239 response->setCiaddr(newest->addr_);
240 if (newest->hwaddr_) {
241 response->setHWAddr(newest->hwaddr_);
263 Pkt4Ptr response(
new Pkt4(response_type, query->getTransid()));
264 response->setGiaddr(query->getGiaddr());
270 response->setRemoteAddr(query->getGiaddr());
271 response->setRemotePort(DHCP4_SERVER_PORT);
273 HWAddrPtr dst_hw_addr = query->getRemoteHWAddr();
275 response->setRemoteHWAddr(dst_hw_addr);
279 IOAddress local_addr = query->getLocalAddr();
284 response->setLocalAddr(local_addr);
285 response->setLocalPort(query->getLocalPort());
286 response->setIface(query->getIface());
287 response->setIndex(query->getIndex());
289 HWAddrPtr src_hw_addr = query->getLocalHWAddr();
291 response->setLocalHWAddr(src_hw_addr);
296 if (client_server_id) {
297 response->addOption(client_server_id);
307 for (
auto const& lease : leases) {
308 if (lease->addr_ != response->getCiaddr()) {
309 associates->addAddress(lease->addr_);
315 response->addOption(associates);
327 ->getCfgSubnets4()->getSubnet(lease->subnet_id_);
333 if (lease->client_id_) {
335 lease->client_id_->getClientId()));
336 response->addOption(cid_opt);
355 time_t now = time(0);
359 if (now > lease->cltt_) {
360 elapsed = now - lease->cltt_;
368 response->addOption(opt);
374 response->addOption(opt);
379 time_t adjusted_lft = lease->valid_lft_ - elapsed;
383 response->addOption(opt);
390 if (!subnet->getT2().unspecified()) {
391 t2_time = subnet->getT2();
392 }
else if (subnet->getCalculateTeeTimes()) {
394 t2_time =
static_cast<time_t
>(round(subnet->getT2Percent()
395 * (lease->valid_lft_)));
403 time_t timer_ceiling = adjusted_lft;
404 if (t2_time > 0 && t2_time < timer_ceiling) {
406 response->addOption(t2);
408 timer_ceiling = t2_time;
413 if (!subnet->getT1().unspecified()) {
414 t1_time = subnet->getT1();
415 }
else if (subnet->getCalculateTeeTimes()) {
417 t1_time =
static_cast<time_t
>(round(subnet->getT1Percent()
418 * (lease->valid_lft_)));
426 if (t1_time > 0 && t1_time < timer_ceiling) {
428 response->addOption(t1);
435 if (lease->getContext()) {
444 if (!extended_info) {
448 ConstElementPtr relay_agent_info = extended_info->get(
"relay-agent-info");
449 if (!relay_agent_info) {
457 relay_agent_info = relay_agent_info->get(
"sub-options");
458 if (!relay_agent_info) {
464 std::vector<uint8_t> opt_data;
469 response->addOption(rai);
470 }
catch (
const std::exception& ex) {
477 std::stringstream label;
480 label <<
"type: " << packet->getName()
481 <<
", giaddr: " << packet->getGiaddr().toText()
482 <<
", transid: " << packet->getTransid()
483 <<
", ciaddr: " << packet->getCiaddr().toText();
486 label <<
", hwaddr: " << (hwaddr ? hwaddr->toText() :
"none");
490 label <<
", cid: none";
493 ClientId client_id(client_opt->getData());
494 label <<
", cid: " << client_id.
toText();
496 label <<
", cid: (malformed)";
499 }
catch (
const std::exception& ex) {
501 label <<
"label error" << ex.what();
504 return (label.str());
512 }
catch (
const std::exception& ex) {
522 .arg(response->getRemoteAddr())
523 .arg(response->getRemotePort());
526 switch (response->getType()) {
529 static_cast<int64_t
>(1));
533 static_cast<int64_t
>(1));
537 static_cast<int64_t
>(1));
544 }
catch (
const std::exception& ex) {
547 .arg(response->getIface())
548 .arg(response->getRemoteAddr())
549 .arg(response->getRemotePort())
559 if (!server_id_opt) {
567 boost::dynamic_pointer_cast<OptionCustom>(server_id_opt);
570 if (!option_custom) {
572 static_cast<int64_t
>(1));
576 if (option_custom->getDataFieldsNum() != 1) {
578 static_cast<int64_t
>(1));
583 IOAddress client_server_id = option_custom->readAddress();
584 if (!client_server_id.
isV4() ||
587 static_cast<int64_t
>(1));
601 if (cfg_subnets->hasSubnetWithServerId(client_server_id)) {
608 if (cfg_networks->hasNetworkWithServerId(client_server_id)) {
614 for (
auto const& cclass : classes) {
617 getClientClassDictionary()->findClass(cclass);
622 if (ccdef->getCfgOption()->empty()) {
627 OptionCustomPtr context_opt_server_id = boost::dynamic_pointer_cast<OptionCustom>
629 if (context_opt_server_id && (context_opt_server_id->readAddress() == client_server_id)) {
636 OptionCustomPtr cfg_server_id = boost::dynamic_pointer_cast<OptionCustom>
639 if (cfg_server_id && (cfg_server_id->readAddress() == client_server_id)) {
645 static_cast<int64_t
>(1));
657 for (
auto const& cfg_options : co_list) {
661 response->addOption(server_id_desc.
option_);
669 server_id->writeAddress(response->getLocalAddr());
670 response->addOption(server_id);
692 if (pool && !pool->getCfgOption()->empty()) {
693 co_list.push_back(pool->getCfgOption());
697 if (!subnet->getCfgOption()->empty()) {
698 co_list.push_back(subnet->getCfgOption());
703 subnet->getSharedNetwork(network);
704 if (network && !network->getCfgOption()->empty()) {
705 co_list.push_back(network->getCfgOption());
710 for (
auto const& cclass : classes) {
713 getClientClassDictionary()->findClass(cclass);
719 if (ccdef->getCfgOption()->empty()) {
724 co_list.push_back(ccdef->getCfgOption());
742 upgraded = lease_mgr.upgradeExtendedInfo4(page_size);
743 }
catch (
const std::exception& ex) {
751 std::ostringstream msg;
752 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 const uint32_t STATE_DEFAULT
A lease in the default state.