28namespace ph = std::placeholders;
36 getMACSources().get();
38 for (
auto const& source : mac_sources) {
39 hwaddr = pkt.
getMAC(source);
53 const std::vector<uint8_t>&
id,
76 std::vector<uint8_t>&
id,
83 bool extracted =
false;
105 clientid.reset(
new ClientId(option->getData()));
106 id = clientid->getClientId();
107 if ((
id.size() <= 5) || (
id[0] != CLIENT_ID_OPTION_TYPE_DUID)) {
110 id = vector<uint8_t>(
id.begin() + 5,
id.end());
127 id = option->getData();
143 clientid.reset(
new ClientId(option->getData()));
144 id = clientid->getClientId();
155 vector<uint8_t> popped =
pop0(clientid);
159 text =
toHex(popped);
174 clientid.reset(
new ClientId(option->getData()));
175 id = clientid->getClientId();
176 if ((
id.size() <= 1) || (
id[0] != 0)) {
179 id = vector<uint8_t>(
id.begin() + 1,
id.end());
190 }
catch (
const std::exception& ex) {
209 std::vector<uint8_t>&
id,
222 duid.reset(
new DUID(option->getData()));
223 id = duid->getDuid();
228 vector<uint8_t> popped =
pop0(duid);
232 text =
toHex(popped);
242 hwaddr = getMAC(query);
246 id = hwaddr->hwaddr_;
250 text = hwaddr->toText(
false);
261 duid.reset(
new DUID(option->getData()));
262 id = duid->getDuid();
263 if ((
id.size() <= 2) || (
id[0] != 0) || (
id[1] != 0)) {
266 id = vector<uint8_t>(
id.begin() + 2,
id.end());
277 }
catch (
const std::exception& ex) {
297 const std::vector<uint8_t>&
id,
298 const std::string& text) {
302 if (subnet_id == SUBNET_ID_UNUSED) {
311 hwaddr && !hwaddr->hwaddr_.empty()) {
312 string hw = hwaddr->toText(
false);
323 }
catch (
const std::exception& ex) {
335 env, ph::_1, ph::_2)));
342 const std::vector<uint8_t>&
id,
343 const std::string& text) {
347 if (subnet_id == SUBNET_ID_UNUSED) {
356 hwaddr && !hwaddr->hwaddr_.empty()) {
357 string hw = hwaddr->toText(
false);
368 }
catch (
const std::exception& ex) {
380 env, ph::_1, ph::_2)));
386 bool& both_global,
const std::string& cclass) {
397 if (subnet->clientSupported(query->classes_)) {
399 for (
auto const& pool : pools) {
400 if (pool->clientSupported(cclass)) {
406 bool use_global = subnet->getReservationsGlobal();
412 for (
auto const& iter : *subnets) {
415 for (
auto const& pool : pools) {
416 if (pool->clientSupported(cclass)) {
417 selectable->add(iter);
424 subnet = selectable->selectSubnet(selector);
427 subnet_id = SUBNET_ID_UNUSED;
429 subnet_id = subnet->getID();
430 if (use_global && subnet->getReservationsGlobal()) {
439 bool& both_global,
const std::string& cclass) {
450 if (subnet->clientSupported(query->classes_)) {
452 for (
auto const& pool : pools) {
453 if (pool->clientSupported(cclass)) {
459 bool use_global = subnet->getReservationsGlobal();
465 for (
auto const& iter : *subnets) {
468 for (
auto const& pool : pools) {
469 if (pool->clientSupported(cclass)) {
470 selectable->add(iter);
477 subnet = selectable->selectSubnet(selector);
480 subnet_id = SUBNET_ID_UNUSED;
482 subnet_id = subnet->getID();
483 if (use_global && subnet->getReservationsGlobal()) {
505 if (subnet->clientSupported(query->classes_) && subnet->inRange(address)) {
509 bool use_global = subnet->getReservationsGlobal();
512 subnet = subnets4->selectSubnet(address, query->classes_);
514 subnet_id = SUBNET_ID_UNUSED;
516 subnet_id = subnet->getID();
517 if (use_global && subnet->getReservationsGlobal()) {
539 if (subnet->clientSupported(query->classes_) && subnet->inRange(address)) {
543 bool use_global = subnet->getReservationsGlobal();
546 subnet = subnets6->selectSubnet(address, query->classes_);
548 subnet_id = SUBNET_ID_UNUSED;
550 subnet_id = subnet->getID();
551 if (use_global && subnet->getReservationsGlobal()) {
567 impl.auth_->requests4_.get(env.
id_);
568 if (!pending_request) {
575 query = pending_request->query_;
576 impl.auth_->requests4_.remove(env.
id_);
582 bool reselected =
false;
583 bool both_global =
false;
593 }
else if (result !=
OK_RC) {
601 }
else if (recv_attrs) {
611 if (framed_pool && (framed_pool->getValueType() ==
PW_TYPE_STRING)) {
612 cclass = framed_pool->toString();
614 query->addClass(cclass);
620 if (ip_address && (ip_address->getValueType() ==
PW_TYPE_IPADDR)) {
621 addr4 = ip_address->toIpAddr();
625 if (query && !reselected && !cclass.empty() &&
626 impl.reselect_subnet_pool_) {
631 if (query && !reselected && !addr4.
isV4Zero() &&
632 impl.reselect_subnet_address_) {
642 map->set(
"subnet-id",
647 uint32_t host_subnet_id = SUBNET_ID_UNUSED;
648 if (reselected && !both_global) {
650 getCfgSubnets4()->getBySubnetId(original_subnet_id);
655 ((subnet && subnet->getReservationsGlobal()) ?
656 SUBNET_ID_GLOBAL : original_subnet_id);
660 host_subnet_id, SUBNET_ID_UNUSED,
664 host->setContext(map);
668 host->setNegative(
true);
674 static_cast<void>(cache->insert(host,
true));
691 getCfgSubnets4()->getBySubnetId(env.
subnet_id_);
696 ((subnet && subnet->getReservationsGlobal()) ?
699 host_subnet_id, SUBNET_ID_UNUSED, addr4));
703 map->set(
"radius", recv_attrs->toElement());
705 host->setContext(map);
709 host->setNegative(
true);
716 cache->insert(host,
true);
720 .arg(recv_attrs ? recv_attrs->toText() :
"");
725 callout_handle->setContext(
"subnet4", subnet);
736 }
catch (
const std::exception& ex) {
744 .arg(
"unknown error");
753 .arg(query->getLabel());
764 .arg(query->getLabel())
779 impl.auth_->requests6_.get(env.
id_);
780 if (!pending_request) {
787 query = pending_request->query_;
788 impl.auth_->requests6_.remove(env.
id_);
795 bool reselected =
false;
796 bool both_global =
false;
806 }
else if (result !=
OK_RC) {
814 }
else if (recv_attrs) {
825 if (framed_pool && (framed_pool->getValueType() ==
PW_TYPE_STRING)) {
826 cclass = framed_pool->toString();
828 query->addClass(cclass);
835 addr6 = ip6_address->toIpv6Addr();
839 uint8_t pref_len = 0;
842 pref_len = prefix->toIpv6PrefixLen();
843 pref_addr = prefix->toIpv6Prefix();
847 if (query && !reselected && !cclass.empty() &&
848 impl.reselect_subnet_pool_) {
853 if (query && !reselected && !addr6.
isV6Zero() &&
854 impl.reselect_subnet_address_) {
866 map->set(
"subnet-id",
871 uint32_t host_subnet_id = SUBNET_ID_UNUSED;
872 if (reselected && !both_global) {
874 getCfgSubnets6()->getBySubnetId(original_subnet_id);
879 ((subnet && subnet->getReservationsGlobal()) ?
880 SUBNET_ID_GLOBAL : original_subnet_id);
884 SUBNET_ID_UNUSED, host_subnet_id,
888 host->setContext(map);
892 host->setNegative(
true);
898 static_cast<void>(cache->insert(host,
true));
915 getCfgSubnets6()->getBySubnetId(env.
subnet_id_);
920 ((subnet && subnet->getReservationsGlobal()) ?
923 SUBNET_ID_UNUSED, host_subnet_id,
928 map->set(
"radius", recv_attrs->toElement());
930 host->setContext(map);
933 bool has_reservation =
false;
937 has_reservation =
true;
943 if (pref_len && !pref_addr.
isV6Zero()) {
947 has_reservation =
true;
952 if (!has_reservation) {
954 host->setNegative(
true);
961 cache->insert(host,
true);
965 .arg(recv_attrs ? recv_attrs->toText() :
"");
970 callout_handle->setContext(
"subnet6", subnet);
981 }
catch (
const std::exception& ex) {
989 .arg(
"unknown error");
998 .arg(query->getLabel());
1009 .arg(query->getLabel())
static ElementPtr create(const Position &pos=ZERO_POSITION())
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.
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.
IdentifierType
Type of the host identifier.
@ IDENT_FLEX
Flexible host identifier.
static std::string getIdentifierName(const IdentifierType &type)
Returns name of the identifier of a specified type.
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.
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.
Radius hooks library implementation.
dhcp::Host::IdentifierType id_type4_
Identifier type for IPv4.
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.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#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.
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.