31namespace ph = std::placeholders;
39 getMACSources().get();
41 for (
auto const& source : mac_sources) {
42 hwaddr = pkt.
getMAC(source);
56 const std::vector<uint8_t>&
id,
79 std::vector<uint8_t>&
id,
86 bool extracted =
false;
108 clientid.reset(
new ClientId(option->getData()));
109 id = clientid->getClientId();
110 if ((
id.size() <= 5) || (
id[0] != CLIENT_ID_OPTION_TYPE_DUID)) {
113 id = vector<uint8_t>(
id.begin() + 5,
id.end());
130 id = option->getData();
146 clientid.reset(
new ClientId(option->getData()));
147 id = clientid->getClientId();
158 vector<uint8_t> popped =
pop0(clientid);
162 text =
toHex(popped);
177 clientid.reset(
new ClientId(option->getData()));
178 id = clientid->getClientId();
179 if ((
id.size() <= 1) || (
id[0] != 0)) {
182 id = vector<uint8_t>(
id.begin() + 1,
id.end());
193 }
catch (
const std::exception& ex) {
212 std::vector<uint8_t>&
id,
225 duid.reset(
new DUID(option->getData()));
226 id = duid->getDuid();
231 vector<uint8_t> popped =
pop0(duid);
235 text =
toHex(popped);
245 hwaddr = getMAC(query);
249 id = hwaddr->hwaddr_;
253 text = hwaddr->toText(
false);
264 duid.reset(
new DUID(option->getData()));
265 id = duid->getDuid();
266 if ((
id.size() <= 2) || (
id[0] != 0) || (
id[1] != 0)) {
269 id = vector<uint8_t>(
id.begin() + 2,
id.end());
280 }
catch (
const std::exception& ex) {
300 const std::vector<uint8_t>&
id,
301 const std::string& text) {
305 if (subnet_id == SUBNET_ID_UNUSED) {
314 hwaddr && !hwaddr->hwaddr_.empty()) {
315 string hw = hwaddr->toText(
false);
326 }
catch (
const std::exception& ex) {
338 env, ph::_1, ph::_2)));
345 const std::vector<uint8_t>&
id,
346 const std::string& text) {
350 if (subnet_id == SUBNET_ID_UNUSED) {
359 hwaddr && !hwaddr->hwaddr_.empty()) {
360 string hw = hwaddr->toText(
false);
371 }
catch (
const std::exception& ex) {
383 env, ph::_1, ph::_2)));
389 bool& both_global,
const std::string& cclass) {
400 if (subnet->clientSupported(query->classes_)) {
402 for (
auto const& pool : pools) {
403 if (pool->clientSupported(cclass)) {
409 bool use_global = subnet->getReservationsGlobal();
415 for (
auto const& iter : *subnets) {
418 for (
auto const& pool : pools) {
419 if (pool->clientSupported(cclass)) {
420 selectable->add(iter);
427 subnet = selectable->selectSubnet(selector);
430 subnet_id = SUBNET_ID_UNUSED;
432 subnet_id = subnet->getID();
433 if (use_global && subnet->getReservationsGlobal()) {
442 bool& both_global,
const std::string& cclass) {
453 if (subnet->clientSupported(query->classes_)) {
455 for (
auto const& pool : pools) {
456 if (pool->clientSupported(cclass)) {
462 bool use_global = subnet->getReservationsGlobal();
468 for (
auto const& iter : *subnets) {
471 for (
auto const& pool : pools) {
472 if (pool->clientSupported(cclass)) {
473 selectable->add(iter);
480 subnet = selectable->selectSubnet(selector);
483 subnet_id = SUBNET_ID_UNUSED;
485 subnet_id = subnet->getID();
486 if (use_global && subnet->getReservationsGlobal()) {
508 if (subnet->clientSupported(query->classes_) && subnet->inRange(address)) {
512 bool use_global = subnet->getReservationsGlobal();
515 subnet = subnets4->selectSubnet(address, query->classes_);
517 subnet_id = SUBNET_ID_UNUSED;
519 subnet_id = subnet->getID();
520 if (use_global && subnet->getReservationsGlobal()) {
542 if (subnet->clientSupported(query->classes_) && subnet->inRange(address)) {
546 bool use_global = subnet->getReservationsGlobal();
549 subnet = subnets6->selectSubnet(address, query->classes_);
551 subnet_id = SUBNET_ID_UNUSED;
553 subnet_id = subnet->getID();
554 if (use_global && subnet->getReservationsGlobal()) {
570 impl.auth_->requests4_.get(env.
id_);
571 if (!pending_request) {
578 query = pending_request->query_;
579 impl.auth_->requests4_.remove(env.
id_);
585 bool reselected =
false;
586 bool both_global =
false;
596 }
else if (result !=
OK_RC) {
604 }
else if (recv_attrs) {
614 if (framed_pool && (framed_pool->getValueType() ==
PW_TYPE_STRING)) {
615 cclass = framed_pool->toString();
617 query->addClass(cclass);
623 if (ip_address && (ip_address->getValueType() ==
PW_TYPE_IPADDR)) {
624 addr4 = ip_address->toIpAddr();
628 if (query && !reselected && !cclass.empty() &&
629 impl.reselect_subnet_pool_) {
634 if (query && !reselected && !addr4.
isV4Zero() &&
635 impl.reselect_subnet_address_) {
645 map->set(
"subnet-id",
650 uint32_t host_subnet_id = SUBNET_ID_UNUSED;
651 if (reselected && !both_global) {
653 getCfgSubnets4()->getBySubnetId(original_subnet_id);
658 ((subnet && subnet->getReservationsGlobal()) ?
659 SUBNET_ID_GLOBAL : original_subnet_id);
663 host_subnet_id, SUBNET_ID_UNUSED,
667 host->setContext(map);
671 host->setNegative(
true);
677 static_cast<void>(cache->insert(host,
true));
694 getCfgSubnets4()->getBySubnetId(env.
subnet_id_);
699 ((subnet && subnet->getReservationsGlobal()) ?
702 host_subnet_id, SUBNET_ID_UNUSED, addr4));
706 map->set(
"radius", recv_attrs->toElement());
708 host->setContext(map);
712 host->setNegative(
true);
719 cache->insert(host,
true);
723 .arg(recv_attrs ? recv_attrs->toText() :
"");
728 callout_handle->setContext(
"subnet4", subnet);
739 }
catch (
const std::exception& ex) {
747 .arg(
"unknown error");
756 .arg(query->getLabel());
758 static_cast<int64_t
>(1));
760 static_cast<int64_t
>(1));
771 .arg(query->getLabel())
786 impl.auth_->requests6_.get(env.
id_);
787 if (!pending_request) {
794 query = pending_request->query_;
795 impl.auth_->requests6_.remove(env.
id_);
802 bool reselected =
false;
803 bool both_global =
false;
813 }
else if (result !=
OK_RC) {
821 }
else if (recv_attrs) {
832 if (framed_pool && (framed_pool->getValueType() ==
PW_TYPE_STRING)) {
833 cclass = framed_pool->toString();
835 query->addClass(cclass);
842 addr6 = ip6_address->toIpv6Addr();
846 uint8_t pref_len = 0;
849 pref_len = prefix->toIpv6PrefixLen();
850 pref_addr = prefix->toIpv6Prefix();
854 if (query && !reselected && !cclass.empty() &&
855 impl.reselect_subnet_pool_) {
860 if (query && !reselected && !addr6.
isV6Zero() &&
861 impl.reselect_subnet_address_) {
873 map->set(
"subnet-id",
878 uint32_t host_subnet_id = SUBNET_ID_UNUSED;
879 if (reselected && !both_global) {
881 getCfgSubnets6()->getBySubnetId(original_subnet_id);
886 ((subnet && subnet->getReservationsGlobal()) ?
887 SUBNET_ID_GLOBAL : original_subnet_id);
891 SUBNET_ID_UNUSED, host_subnet_id,
895 host->setContext(map);
899 host->setNegative(
true);
905 static_cast<void>(cache->insert(host,
true));
922 getCfgSubnets6()->getBySubnetId(env.
subnet_id_);
927 ((subnet && subnet->getReservationsGlobal()) ?
930 SUBNET_ID_UNUSED, host_subnet_id,
935 map->set(
"radius", recv_attrs->toElement());
937 host->setContext(map);
940 bool has_reservation =
false;
944 has_reservation =
true;
950 if (pref_len && !pref_addr.
isV6Zero()) {
954 has_reservation =
true;
959 if (!has_reservation) {
961 host->setNegative(
true);
968 cache->insert(host,
true);
972 .arg(recv_attrs ? recv_attrs->toText() :
"");
977 callout_handle->setContext(
"subnet6", subnet);
988 }
catch (
const std::exception& ex) {
996 .arg(
"unknown error");
1005 .arg(query->getLabel());
1007 static_cast<int64_t
>(1));
1009 static_cast<int64_t
>(1));
1020 .arg(query->getLabel())
1035 if (secs > 24*60*60) {
static ElementPtr create(const Position &pos=ZERO_POSITION())
Create a NullElement.
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
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 if a parameter given to a method would refer to or modify out-of-r...
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.
bool isV6Zero() const
Convenience function to check if it is an IPv4 zero address.
static const IOAddress & IPV6_ZERO_ADDRESS()
Returns an IPv6 zero address.
The IntervalTimer class is a wrapper for the ASIO boost::asio::system_timer class.
static CfgMgr & instance()
returns a single instance of Configuration Manager
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Holds subnets configured for the DHCPv4 server.
static SubnetSelector initSelector(const Pkt4Ptr &query)
Build selector from a client's message.
Holds subnets configured for the DHCPv6 server.
static SubnetSelector initSelector(const Pkt6Ptr &query)
Build selector from a client's message.
Holds Client identifier or client IPv4 address.
Holds DUID (DHCPv6 Unique Identifier)
Represents a device with IPv4 and/or IPv6 reservations.
static std::string getIdentifierName(const IdentifierType &type)
Returns name of the identifier of a specified type.
IdentifierType
Type of the host identifier.
@ IDENT_FLEX
Flexible host identifier.
IPv6 reservation for a host.
Represents DHCPv4 packet.
std::string getLabel() const
Returns text representation of the primary packet identifiers.
HWAddrPtr getHWAddr() const
returns hardware address information
Represents a DHCPv6 packet.
virtual std::string getLabel() const
Returns text representation of the primary packet identifiers.
OptionPtr getOption(const uint16_t type)
Returns the first option of specified type.
HWAddrPtr getMAC(uint32_t hw_addr_src)
Returns MAC address.
static bool unpark(const std::string &hook_name, T parked_object)
Forces unparking the object (packet).
static bool drop(const std::string &hook_name, T parked_object)
Removes parked object without calling a callback.
static AttributePtr fromString(const uint8_t type, const std::string &value)
From type specific factories.
Collection of attributes.
static void terminate6Internal(RadiusAuthEnv &env, int result, AttributesPtr recv_attrs, dhcp::Pkt6Ptr &query, bool &drop)
Termination callback body - IPv6.
static void terminate4Internal(RadiusAuthEnv &env, int result, AttributesPtr recv_attrs, dhcp::Pkt4Ptr &query, bool &drop)
Termination callback body - IPv4.
static void terminate4(RadiusAuthEnv env, int result, AttributesPtr recv_attrs)
Termination callback - IPv4.
RadiusAccess()
Constructor.
static bool reselectSubnet(const dhcp::Pkt4Ptr &query, uint32_t &subnet_id, bool &both_global, const std::string &cclass)
Subnet reselect - class/pool IPv4.
static void terminate6(RadiusAuthEnv env, int result, AttributesPtr recv_attrs)
Termination callback - IPv6.
bool getIdentifier(dhcp::Pkt4 &query, std::vector< uint8_t > &id, std::string &text)
Get Identifier – IPv4.
void setIdleTimer()
Set idle timer.
static void IdleTimerCallback()
Idle timer callback.
RadiusAuthHandlerPtr buildAuth(dhcp::Pkt4 &query, uint32_t subnet_id, const std::vector< uint8_t > &id, const std::string &text)
Build RadiusAuth handler for Access-Request - IPv4.
class for asynchronous authentication communication with servers.
Class of Radius access environments.
RadiusAuthEnv(uint32_t subnet_id, const std::vector< uint8_t > &id, AttributesPtr send_attrs)
Constructor.
const std::vector< uint8_t > id_
Identifier.
uint32_t subnet_id_
Subnet Id (aka client/NAS port).
AttributesPtr send_attrs_
Attributes to send.
Class of Radius access communication handler.
RadiusAuthHandler(RadiusAuthEnv env, const CallbackAuth &callback)
Constructor.
RadiusAuthEnv env_
Environment.
void start()
Start communication.
RadiusAsyncAuthPtr auth_
Pointer to the communication class.
Class for communication with access servers.
Radius hooks library implementation.
dhcp::Host::IdentifierType id_type4_
Identifier type for IPv4.
void registerExchange(ExchangePtr exchange)
Register Exchange.
dhcp::Host::IdentifierType id_type6_
Identifier type for IPv6.
static RadiusImpl & instance()
RadiusImpl is a singleton class.
CfgAttributes attributes_
Attribute configurations.
RadiusService(const std::string &name)
Constructor.
asiolink::IntervalTimerPtr idle_timer_
Idle timer.
long idle_timer_interval_
Idle timer interval in seconds.
void cancelIdleTimer()
Cancel idle timer.
static std::mutex idle_timer_mutex_
Idle timer mutex.
static StatsMgr & instance()
Statistics Manager accessor method.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
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.
boost::shared_ptr< Element > ElementPtr
@ DHO_DHCP_CLIENT_IDENTIFIER
boost::shared_ptr< const Subnet6 > ConstSubnet6Ptr
A const pointer to a Subnet6 object.
std::vector< uint32_t > CfgMACSources
Container for defined MAC/hardware address sources.
boost::shared_ptr< Host > HostPtr
Pointer to the Host object.
boost::shared_ptr< const Subnet4 > ConstSubnet4Ptr
A const pointer to a Subnet4 object.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
boost::shared_ptr< DUID > DuidPtr
boost::multi_index_container< Subnet6Ptr, 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< SubnetModificationTimeIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime, &data::BaseStampedElement::getModificationTime > > > > Subnet6Collection
A collection of Subnet6 objects.
std::vector< PoolPtr > PoolCollection
a container for either IPv4 or IPv6 Pools
boost::shared_ptr< CfgSubnets6 > CfgSubnets6Ptr
Non-const pointer.
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
isc::hooks::CalloutHandlePtr getCalloutHandle(const T &pktptr)
CalloutHandle Store.
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< CacheHostDataSource > CacheHostDataSourcePtr
CacheHostDataSource pointer.
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
boost::shared_ptr< CfgSubnets4 > CfgSubnets4Ptr
Non-const pointer.
boost::shared_ptr< const CfgSubnets4 > ConstCfgSubnets4Ptr
Const pointer.
boost::shared_ptr< const CfgSubnets6 > ConstCfgSubnets6Ptr
Const pointer.
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
@ RAI_OPTION_AGENT_CIRCUIT_ID
boost::shared_ptr< Option > OptionPtr
boost::shared_ptr< CalloutHandle > CalloutHandlePtr
A shared pointer to a CalloutHandle object.
@ PW_DELEGATED_IPV6_PREFIX
ipv6prefix.
@ PW_FRAMED_IP_ADDRESS
ipaddr.
@ PW_CALLING_STATION_ID
string.
@ PW_FRAMED_IPV6_ADDRESS
ipv6addr.
boost::shared_ptr< RadiusAuthPendingRequest< PktPtrType > > RadiusAuthPendingRequestPtr
Pointer to a pending Radius access request.
vector< uint8_t > extractDuid(const ClientIdPtr &client_id, bool &extracted)
Extract the duid from a RFC 4361 compliant DHCPv4 client ID.
string canonize(const string &hexdump)
Canonize hardware address textual representation.
const isc::log::MessageID RADIUS_ACCESS_BUILD_FAILED
boost::shared_ptr< Attributes > AttributesPtr
Shared pointers to attribute collection.
const isc::log::MessageID RADIUS_ACCESS_RESUME_PARKED_QUERY
boost::shared_ptr< const Attribute > ConstAttributePtr
const isc::log::MessageID RADIUS_ACCESS_TERMINATE_ERROR
string exchangeRCtoText(const int rc)
ExchangeRC value -> name function.
const isc::log::MessageID RADIUS_ACCESS_CACHE_INSERT
const isc::log::MessageID RADIUS_ACCESS_GET_IDENTIFIER_FAILED
const int RADIUS_DBG_TRACE
Radius logging levels.
boost::shared_ptr< RadiusAuthStatus > RadiusAuthStatusPtr
Pointer to access status.
string toPrintable(const vector< uint8_t > &content)
Return printable textual representation of a vector.
const isc::log::MessageID RADIUS_ACCESS_ORPHAN
const isc::log::MessageID RADIUS_ACCESS_ERROR
string toHex(const vector< uint8_t > &content)
Return hexadecimal textual representation of a vector.
const isc::log::MessageID RADIUS_ACCESS_DROP_PARKED_QUERY
std::function< void(int, AttributesPtr)> CallbackAuth
Type of callback for authentication termination.
boost::shared_ptr< RadiusAuthHandler > RadiusAuthHandlerPtr
Type of pointers to Radius access communication handler.
isc::log::Logger radius_logger("radius-hooks")
Radius Logger.
vector< uint8_t > pop0(const ClientIdPtr &client_id)
Pop leading zero in a DHCPv4 client-id.
const isc::log::MessageID RADIUS_ACCESS_GET_IDENTIFIER
Defines the logger used by the top-level component of kea-lfc.
@ TYPE_NA
the lease contains non-temporary IPv6 address
Subnet selector used to specify parameters used to select a subnet.
RAII lock object to protect the code in the same scope with a mutex.