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();
71 << requester_ip.
toText() <<
", unknown server-id: "
72 << (client_server_id ? client_server_id->toText() :
"malformed"));
79 uint8_t query_mask = (!ciaddr.
isV4Zero() ? 1 : 0);
82 query_mask |= ((hwaddr->htype_ || hwaddr->hwaddr_.size()) ? 2 : 0);
87 client_id.reset(
new ClientId(opt->getData()));
112 <<
"ciaddr: [" << ciaddr
113 <<
"] HWAddr: [" << hwaddr->
toText()
114 <<
"] Client id: [" << (client_id ? client_id->toText() :
"")
132 leases.push_back(lease);
145 for (
auto const& subnet : *subnets) {
176 if (!found_leases.empty()) {
177 for (
auto const& lease : found_leases) {
179 active_leases.push_back(lease);
183 std::sort(active_leases.begin(), active_leases.end(), cltt_descending);
186 return (active_leases);
196 switch(response_type) {
205 response->setCiaddr(query->getCiaddr());
206 response->setHWAddr(query->getHWAddr());
209 response->addOption(opt);
220 if (leases.size() == 0) {
228 response->setCiaddr(newest->addr_);
229 if (newest->hwaddr_) {
230 response->setHWAddr(newest->hwaddr_);
252 Pkt4Ptr response(
new Pkt4(response_type, query->getTransid()));
253 response->setGiaddr(query->getGiaddr());
259 response->setRemoteAddr(query->getGiaddr());
260 response->setRemotePort(DHCP4_SERVER_PORT);
262 HWAddrPtr dst_hw_addr = query->getRemoteHWAddr();
264 response->setRemoteHWAddr(dst_hw_addr);
268 IOAddress local_addr = query->getLocalAddr();
273 response->setLocalAddr(local_addr);
274 response->setLocalPort(query->getLocalPort());
275 response->setIface(query->getIface());
276 response->setIndex(query->getIndex());
278 HWAddrPtr src_hw_addr = query->getLocalHWAddr();
280 response->setLocalHWAddr(src_hw_addr);
285 if (client_server_id) {
286 response->addOption(client_server_id);
296 for (
auto const& lease : leases) {
297 if (lease->addr_ != response->getCiaddr()) {
298 associates->addAddress(lease->addr_);
304 response->addOption(associates);
316 ->getCfgSubnets4()->getSubnet(lease->subnet_id_);
322 if (lease->client_id_) {
324 lease->client_id_->getClientId()));
325 response->addOption(cid_opt);
344 time_t now = time(0);
348 if (now > lease->cltt_) {
349 elapsed = now - lease->cltt_;
357 response->addOption(opt);
363 response->addOption(opt);
368 time_t adjusted_lft = lease->valid_lft_ - elapsed;
372 response->addOption(opt);
379 if (!subnet->getT2().unspecified()) {
380 t2_time = subnet->getT2();
381 }
else if (subnet->getCalculateTeeTimes()) {
383 t2_time =
static_cast<time_t
>(round(subnet->getT2Percent()
384 * (lease->valid_lft_)));
392 time_t timer_ceiling = adjusted_lft;
393 if (t2_time > 0 && t2_time < timer_ceiling) {
395 response->addOption(t2);
397 timer_ceiling = t2_time;
402 if (!subnet->getT1().unspecified()) {
403 t1_time = subnet->getT1();
404 }
else if (subnet->getCalculateTeeTimes()) {
406 t1_time =
static_cast<time_t
>(round(subnet->getT1Percent()
407 * (lease->valid_lft_)));
415 if (t1_time > 0 && t1_time < timer_ceiling) {
417 response->addOption(t1);
424 if (lease->getContext()) {
433 if (!extended_info) {
437 ConstElementPtr relay_agent_info = extended_info->get(
"relay-agent-info");
438 if (!relay_agent_info) {
446 relay_agent_info = relay_agent_info->get(
"sub-options");
447 if (!relay_agent_info) {
453 std::vector<uint8_t> opt_data;
458 response->addOption(rai);
459 }
catch (
const std::exception& ex) {
466 std::stringstream label;
469 label <<
"type: " << packet->getName()
470 <<
", giaddr: " << packet->getGiaddr().toText()
471 <<
", transid: " << packet->getTransid()
472 <<
", ciaddr: " << packet->getCiaddr().toText();
475 label <<
", hwaddr: " << (hwaddr ? hwaddr->toText() :
"none");
479 label <<
", cid: none";
482 ClientId client_id(client_opt->getData());
483 label <<
", cid: " << client_id.
toText();
485 label <<
", cid: (malformed)";
488 }
catch (
const std::exception& ex) {
490 label <<
"label error" << ex.what();
493 return (label.str());
501 }
catch (
const std::exception& ex) {
511 .arg(response->getRemoteAddr())
512 .arg(response->getRemotePort());
515 switch (response->getType()) {
518 static_cast<int64_t
>(1));
522 static_cast<int64_t
>(1));
526 static_cast<int64_t
>(1));
533 }
catch (
const std::exception& ex) {
536 .arg(response->getIface())
537 .arg(response->getRemoteAddr())
538 .arg(response->getRemotePort())
548 if (!server_id_opt) {
556 boost::dynamic_pointer_cast<OptionCustom>(server_id_opt);
559 if (!option_custom) {
563 if (option_custom->getDataFieldsNum() != 1) {
568 IOAddress client_server_id = option_custom->readAddress();
569 if (!client_server_id.
isV4() ||
584 if (cfg_subnets->hasSubnetWithServerId(client_server_id)) {
591 if (cfg_networks->hasNetworkWithServerId(client_server_id)) {
597 for (
auto const& cclass : classes) {
600 getClientClassDictionary()->findClass(cclass);
605 if (ccdef->getCfgOption()->empty()) {
610 OptionCustomPtr context_opt_server_id = boost::dynamic_pointer_cast<OptionCustom>
612 if (context_opt_server_id && (context_opt_server_id->readAddress() == client_server_id)) {
619 OptionCustomPtr cfg_server_id = boost::dynamic_pointer_cast<OptionCustom>
622 return (cfg_server_id && (cfg_server_id->readAddress() == client_server_id));
633 for (
auto const& cfg_options : co_list) {
637 response->addOption(server_id_desc.
option_);
645 server_id->writeAddress(response->getLocalAddr());
646 response->addOption(server_id);
668 if (pool && !pool->getCfgOption()->empty()) {
669 co_list.push_back(pool->getCfgOption());
673 if (!subnet->getCfgOption()->empty()) {
674 co_list.push_back(subnet->getCfgOption());
679 subnet->getSharedNetwork(network);
680 if (network && !network->getCfgOption()->empty()) {
681 co_list.push_back(network->getCfgOption());
686 for (
auto const& cclass : classes) {
689 getClientClassDictionary()->findClass(cclass);
695 if (ccdef->getCfgOption()->empty()) {
700 co_list.push_back(ccdef->getCfgOption());
718 upgraded = lease_mgr.upgradeExtendedInfo4(page_size);
719 }
catch (
const std::exception& ex) {
727 std::ostringstream msg;
728 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(dhcp::PktPtr base_query) 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.