35namespace ph = std::placeholders;
43 getMACSources().get();
45 for (
auto const& source : mac_sources) {
46 hwaddr = pkt.
getMAC(source);
60 const std::vector<uint8_t>&
id,
83 std::vector<uint8_t>&
id,
90 bool extracted =
false;
112 clientid.reset(
new ClientId(option->getData()));
113 id = clientid->getClientId();
114 if ((
id.size() <= 5) || (
id[0] != CLIENT_ID_OPTION_TYPE_DUID)) {
117 id = vector<uint8_t>(
id.begin() + 5,
id.end());
134 id = option->getData();
150 clientid.reset(
new ClientId(option->getData()));
151 id = clientid->getClientId();
162 vector<uint8_t> popped =
pop0(clientid);
181 clientid.reset(
new ClientId(option->getData()));
182 id = clientid->getClientId();
183 if ((
id.size() <= 1) || (
id[0] != 0)) {
186 id = vector<uint8_t>(
id.begin() + 1,
id.end());
197 }
catch (
const std::exception& ex) {
216 std::vector<uint8_t>&
id,
229 duid.reset(
new DUID(option->getData()));
230 id = duid->getDuid();
235 vector<uint8_t> popped =
pop0(duid);
249 hwaddr = getMAC(query);
253 id = hwaddr->hwaddr_;
257 text = hwaddr->toText(
false);
268 duid.reset(
new DUID(option->getData()));
269 id = duid->getDuid();
270 if ((
id.size() <= 2) || (
id[0] != 0) || (
id[1] != 0)) {
273 id = vector<uint8_t>(
id.begin() + 2,
id.end());
284 }
catch (
const std::exception& ex) {
304 const std::vector<uint8_t>&
id,
305 const std::string& text) {
309 if (subnet_id == SUBNET_ID_UNUSED) {
318 hwaddr && !hwaddr->hwaddr_.empty()) {
319 string hw = hwaddr->toText(
false);
330 }
catch (
const std::exception& ex) {
342 env, ph::_1, ph::_2)));
349 const std::vector<uint8_t>&
id,
350 const std::string& text) {
354 if (subnet_id == SUBNET_ID_UNUSED) {
363 hwaddr && !hwaddr->hwaddr_.empty()) {
364 string hw = hwaddr->toText(
false);
375 }
catch (
const std::exception& ex) {
387 env, ph::_1, ph::_2)));
393 bool& both_global,
const std::string& cclass) {
404 if (subnet->clientSupported(query->classes_)) {
406 for (
auto const& pool : pools) {
407 if (pool->clientSupported(cclass)) {
413 bool use_global = subnet->getReservationsGlobal();
419 for (
auto const& iter : *subnets) {
422 for (
auto const& pool : pools) {
423 if (pool->clientSupported(cclass)) {
424 selectable->add(iter);
431 subnet = selectable->selectSubnet(selector);
434 subnet_id = SUBNET_ID_UNUSED;
436 subnet_id = subnet->getID();
437 if (use_global && subnet->getReservationsGlobal()) {
446 bool& both_global,
const std::string& cclass) {
457 if (subnet->clientSupported(query->classes_)) {
459 for (
auto const& pool : pools) {
460 if (pool->clientSupported(cclass)) {
466 bool use_global = subnet->getReservationsGlobal();
472 for (
auto const& iter : *subnets) {
475 for (
auto const& pool : pools) {
476 if (pool->clientSupported(cclass)) {
477 selectable->add(iter);
484 subnet = selectable->selectSubnet(selector);
487 subnet_id = SUBNET_ID_UNUSED;
489 subnet_id = subnet->getID();
490 if (use_global && subnet->getReservationsGlobal()) {
512 if (subnet->clientSupported(query->classes_) && subnet->inRange(address)) {
516 bool use_global = subnet->getReservationsGlobal();
519 subnet = subnets4->selectSubnet(address, query->classes_);
521 subnet_id = SUBNET_ID_UNUSED;
523 subnet_id = subnet->getID();
524 if (use_global && subnet->getReservationsGlobal()) {
546 if (subnet->clientSupported(query->classes_) && subnet->inRange(address)) {
550 bool use_global = subnet->getReservationsGlobal();
553 subnet = subnets6->selectSubnet(address, query->classes_);
555 subnet_id = SUBNET_ID_UNUSED;
557 subnet_id = subnet->getID();
558 if (use_global && subnet->getReservationsGlobal()) {
574 impl.auth_->requests4_.get(env.
id_);
575 if (!pending_request) {
582 query = pending_request->query_;
583 impl.auth_->requests4_.remove(env.
id_);
589 bool reselected =
false;
590 bool both_global =
false;
600 }
else if (result !=
OK_RC) {
608 }
else if (recv_attrs) {
618 if (framed_pool && (framed_pool->getValueType() ==
PW_TYPE_STRING)) {
619 cclass = framed_pool->toString();
621 query->addClass(cclass);
627 if (ip_address && (ip_address->getValueType() ==
PW_TYPE_IPADDR)) {
628 addr4 = ip_address->toIpAddr();
632 if (query && !reselected && !cclass.empty() &&
633 impl.reselect_subnet_pool_) {
638 if (query && !reselected && !addr4.
isV4Zero() &&
639 impl.reselect_subnet_address_) {
649 map->set(
"subnet-id",
654 uint32_t host_subnet_id = SUBNET_ID_UNUSED;
655 if (reselected && !both_global) {
657 getCfgSubnets4()->getBySubnetId(original_subnet_id);
662 ((subnet && subnet->getReservationsGlobal()) ?
663 SUBNET_ID_GLOBAL : original_subnet_id);
667 host_subnet_id, SUBNET_ID_UNUSED,
671 host->setContext(map);
675 host->setNegative(
true);
681 static_cast<void>(cache->insert(host,
true));
698 getCfgSubnets4()->getBySubnetId(env.
subnet_id_);
703 ((subnet && subnet->getReservationsGlobal()) ?
706 host_subnet_id, SUBNET_ID_UNUSED, addr4));
710 map->set(
"radius", recv_attrs->toElement());
712 host->setContext(map);
716 host->setNegative(
true);
723 cache->insert(host,
true);
727 .arg(recv_attrs ? recv_attrs->toText() :
"");
732 callout_handle->setContext(
"subnet4", subnet);
743 }
catch (
const std::exception& ex) {
751 .arg(
"unknown error");
760 .arg(query->getLabel());
762 static_cast<int64_t
>(1));
764 static_cast<int64_t
>(1));
775 .arg(query->getLabel())
790 impl.auth_->requests6_.get(env.
id_);
791 if (!pending_request) {
798 query = pending_request->query_;
799 impl.auth_->requests6_.remove(env.
id_);
806 bool reselected =
false;
807 bool both_global =
false;
817 }
else if (result !=
OK_RC) {
825 }
else if (recv_attrs) {
836 if (framed_pool && (framed_pool->getValueType() ==
PW_TYPE_STRING)) {
837 cclass = framed_pool->toString();
839 query->addClass(cclass);
846 addr6 = ip6_address->toIpv6Addr();
850 uint8_t pref_len = 0;
853 pref_len = prefix->toIpv6PrefixLen();
854 pref_addr = prefix->toIpv6Prefix();
858 if (query && !reselected && !cclass.empty() &&
859 impl.reselect_subnet_pool_) {
864 if (query && !reselected && !addr6.
isV6Zero() &&
865 impl.reselect_subnet_address_) {
877 map->set(
"subnet-id",
882 uint32_t host_subnet_id = SUBNET_ID_UNUSED;
883 if (reselected && !both_global) {
885 getCfgSubnets6()->getBySubnetId(original_subnet_id);
890 ((subnet && subnet->getReservationsGlobal()) ?
891 SUBNET_ID_GLOBAL : original_subnet_id);
895 SUBNET_ID_UNUSED, host_subnet_id,
899 host->setContext(map);
903 host->setNegative(
true);
909 static_cast<void>(cache->insert(host,
true));
926 getCfgSubnets6()->getBySubnetId(env.
subnet_id_);
931 ((subnet && subnet->getReservationsGlobal()) ?
934 SUBNET_ID_UNUSED, host_subnet_id,
939 map->set(
"radius", recv_attrs->toElement());
941 host->setContext(map);
944 bool has_reservation =
false;
948 has_reservation =
true;
954 if (pref_len && !pref_addr.
isV6Zero()) {
958 has_reservation =
true;
963 if (!has_reservation) {
965 host->setNegative(
true);
972 cache->insert(host,
true);
976 .arg(recv_attrs ? recv_attrs->toText() :
"");
981 callout_handle->setContext(
"subnet6", subnet);
992 }
catch (
const std::exception& ex) {
1000 .arg(
"unknown error");
1009 .arg(query->getLabel());
1011 static_cast<int64_t
>(1));
1013 static_cast<int64_t
>(1));
1024 .arg(query->getLabel())
1039 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
@ RAI_OPTION_AGENT_CIRCUIT_ID
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.
@ DHO_DHCP_CLIENT_IDENTIFIER
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.
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.
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
boost::shared_ptr< RadiusAuthPendingRequest< PktPtrType > > RadiusAuthPendingRequestPtr
Pointer to a pending Radius access request.
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
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
string dumpAsHex(const uint8_t *data, size_t length)
Dumps a buffer of bytes as a string of hexadecimal digits.
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.