33namespace ph = std::placeholders;
41 getMACSources().get();
43 for (
auto const& source : mac_sources) {
44 hwaddr = pkt.
getMAC(source);
58 const std::vector<uint8_t>&
id,
81 std::vector<uint8_t>&
id,
88 bool extracted =
false;
110 clientid.reset(
new ClientId(option->getData()));
111 id = clientid->getClientId();
112 if ((
id.size() <= 5) || (
id[0] != CLIENT_ID_OPTION_TYPE_DUID)) {
115 id = vector<uint8_t>(
id.begin() + 5,
id.end());
132 id = option->getData();
148 clientid.reset(
new ClientId(option->getData()));
149 id = clientid->getClientId();
160 vector<uint8_t> popped =
pop0(clientid);
179 clientid.reset(
new ClientId(option->getData()));
180 id = clientid->getClientId();
181 if ((
id.size() <= 1) || (
id[0] != 0)) {
184 id = vector<uint8_t>(
id.begin() + 1,
id.end());
195 }
catch (
const std::exception& ex) {
214 std::vector<uint8_t>&
id,
227 duid.reset(
new DUID(option->getData()));
228 id = duid->getDuid();
233 vector<uint8_t> popped =
pop0(duid);
247 hwaddr = getMAC(query);
251 id = hwaddr->hwaddr_;
255 text = hwaddr->toText(
false);
266 duid.reset(
new DUID(option->getData()));
267 id = duid->getDuid();
268 if ((
id.size() <= 2) || (
id[0] != 0) || (
id[1] != 0)) {
271 id = vector<uint8_t>(
id.begin() + 2,
id.end());
282 }
catch (
const std::exception& ex) {
302 const std::vector<uint8_t>&
id,
303 const std::string& text) {
307 if (subnet_id == SUBNET_ID_UNUSED) {
316 hwaddr && !hwaddr->hwaddr_.empty()) {
317 string hw = hwaddr->toText(
false);
328 }
catch (
const std::exception& ex) {
340 env, ph::_1, ph::_2)));
347 const std::vector<uint8_t>&
id,
348 const std::string& text) {
352 if (subnet_id == SUBNET_ID_UNUSED) {
361 hwaddr && !hwaddr->hwaddr_.empty()) {
362 string hw = hwaddr->toText(
false);
373 }
catch (
const std::exception& ex) {
385 env, ph::_1, ph::_2)));
391 bool& both_global,
const std::string& cclass) {
402 if (subnet->clientSupported(query->classes_)) {
404 for (
auto const& pool : pools) {
405 if (pool->clientSupported(cclass)) {
411 bool use_global = subnet->getReservationsGlobal();
417 for (
auto const& iter : *subnets) {
420 for (
auto const& pool : pools) {
421 if (pool->clientSupported(cclass)) {
422 selectable->add(iter);
429 subnet = selectable->selectSubnet(selector);
432 subnet_id = SUBNET_ID_UNUSED;
434 subnet_id = subnet->getID();
435 if (use_global && subnet->getReservationsGlobal()) {
444 bool& both_global,
const std::string& cclass) {
455 if (subnet->clientSupported(query->classes_)) {
457 for (
auto const& pool : pools) {
458 if (pool->clientSupported(cclass)) {
464 bool use_global = subnet->getReservationsGlobal();
470 for (
auto const& iter : *subnets) {
473 for (
auto const& pool : pools) {
474 if (pool->clientSupported(cclass)) {
475 selectable->add(iter);
482 subnet = selectable->selectSubnet(selector);
485 subnet_id = SUBNET_ID_UNUSED;
487 subnet_id = subnet->getID();
488 if (use_global && subnet->getReservationsGlobal()) {
510 if (subnet->clientSupported(query->classes_) && subnet->inRange(address)) {
514 bool use_global = subnet->getReservationsGlobal();
517 subnet = subnets4->selectSubnet(address, query->classes_);
519 subnet_id = SUBNET_ID_UNUSED;
521 subnet_id = subnet->getID();
522 if (use_global && subnet->getReservationsGlobal()) {
544 if (subnet->clientSupported(query->classes_) && subnet->inRange(address)) {
548 bool use_global = subnet->getReservationsGlobal();
551 subnet = subnets6->selectSubnet(address, query->classes_);
553 subnet_id = SUBNET_ID_UNUSED;
555 subnet_id = subnet->getID();
556 if (use_global && subnet->getReservationsGlobal()) {
572 impl.auth_->requests4_.get(env.
id_);
573 if (!pending_request) {
580 query = pending_request->query_;
581 impl.auth_->requests4_.remove(env.
id_);
587 bool reselected =
false;
588 bool both_global =
false;
598 }
else if (result !=
OK_RC) {
606 }
else if (recv_attrs) {
616 if (framed_pool && (framed_pool->getValueType() ==
PW_TYPE_STRING)) {
617 cclass = framed_pool->toString();
619 query->addClass(cclass);
625 if (ip_address && (ip_address->getValueType() ==
PW_TYPE_IPADDR)) {
626 addr4 = ip_address->toIpAddr();
630 if (query && !reselected && !cclass.empty() &&
631 impl.reselect_subnet_pool_) {
636 if (query && !reselected && !addr4.
isV4Zero() &&
637 impl.reselect_subnet_address_) {
647 map->set(
"subnet-id",
652 uint32_t host_subnet_id = SUBNET_ID_UNUSED;
653 if (reselected && !both_global) {
655 getCfgSubnets4()->getBySubnetId(original_subnet_id);
660 ((subnet && subnet->getReservationsGlobal()) ?
661 SUBNET_ID_GLOBAL : original_subnet_id);
665 host_subnet_id, SUBNET_ID_UNUSED,
669 host->setContext(map);
673 host->setNegative(
true);
679 static_cast<void>(cache->insert(host,
true));
696 getCfgSubnets4()->getBySubnetId(env.
subnet_id_);
701 ((subnet && subnet->getReservationsGlobal()) ?
704 host_subnet_id, SUBNET_ID_UNUSED, addr4));
708 map->set(
"radius", recv_attrs->toElement());
710 host->setContext(map);
714 host->setNegative(
true);
721 cache->insert(host,
true);
725 .arg(recv_attrs ? recv_attrs->toText() :
"");
730 callout_handle->setContext(
"subnet4", subnet);
741 }
catch (
const std::exception& ex) {
749 .arg(
"unknown error");
758 .arg(query->getLabel());
760 static_cast<int64_t
>(1));
762 static_cast<int64_t
>(1));
773 .arg(query->getLabel())
788 impl.auth_->requests6_.get(env.
id_);
789 if (!pending_request) {
796 query = pending_request->query_;
797 impl.auth_->requests6_.remove(env.
id_);
804 bool reselected =
false;
805 bool both_global =
false;
815 }
else if (result !=
OK_RC) {
823 }
else if (recv_attrs) {
834 if (framed_pool && (framed_pool->getValueType() ==
PW_TYPE_STRING)) {
835 cclass = framed_pool->toString();
837 query->addClass(cclass);
844 addr6 = ip6_address->toIpv6Addr();
848 uint8_t pref_len = 0;
851 pref_len = prefix->toIpv6PrefixLen();
852 pref_addr = prefix->toIpv6Prefix();
856 if (query && !reselected && !cclass.empty() &&
857 impl.reselect_subnet_pool_) {
862 if (query && !reselected && !addr6.
isV6Zero() &&
863 impl.reselect_subnet_address_) {
875 map->set(
"subnet-id",
880 uint32_t host_subnet_id = SUBNET_ID_UNUSED;
881 if (reselected && !both_global) {
883 getCfgSubnets6()->getBySubnetId(original_subnet_id);
888 ((subnet && subnet->getReservationsGlobal()) ?
889 SUBNET_ID_GLOBAL : original_subnet_id);
893 SUBNET_ID_UNUSED, host_subnet_id,
897 host->setContext(map);
901 host->setNegative(
true);
907 static_cast<void>(cache->insert(host,
true));
924 getCfgSubnets6()->getBySubnetId(env.
subnet_id_);
929 ((subnet && subnet->getReservationsGlobal()) ?
932 SUBNET_ID_UNUSED, host_subnet_id,
937 map->set(
"radius", recv_attrs->toElement());
939 host->setContext(map);
942 bool has_reservation =
false;
946 has_reservation =
true;
952 if (pref_len && !pref_addr.
isV6Zero()) {
956 has_reservation =
true;
961 if (!has_reservation) {
963 host->setNegative(
true);
970 cache->insert(host,
true);
974 .arg(recv_attrs ? recv_attrs->toText() :
"");
979 callout_handle->setContext(
"subnet6", subnet);
990 }
catch (
const std::exception& ex) {
998 .arg(
"unknown error");
1007 .arg(query->getLabel());
1009 static_cast<int64_t
>(1));
1011 static_cast<int64_t
>(1));
1022 .arg(query->getLabel())
1037 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.
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.