diff options
author | Thomas Markwalder <tmark@isc.org> | 2013-10-28 16:37:53 +0100 |
---|---|---|
committer | Thomas Markwalder <tmark@isc.org> | 2013-10-28 16:37:53 +0100 |
commit | 3b1b5032e2afd07bf7d947e185b59a04d9805e08 (patch) | |
tree | 4b01eb8cd77a1d55ebc7205b9f9f8366a8c78a58 /src/hooks | |
parent | [3207] Added support for default users and delimited user id input (diff) | |
download | kea-3b1b5032e2afd07bf7d947e185b59a04d9805e08.tar.xz kea-3b1b5032e2afd07bf7d947e185b59a04d9805e08.zip |
[3207] Clean and doxygen commentary for user_check hook library.
Adding doxygen and cleaned up code for initial review submission.
Diffstat (limited to 'src/hooks')
-rw-r--r-- | src/hooks/dhcp/user_chk/load_unload.cc | 6 | ||||
-rw-r--r-- | src/hooks/dhcp/user_chk/pkt_receive_co.cc | 36 | ||||
-rw-r--r-- | src/hooks/dhcp/user_chk/pkt_send_co.cc | 98 | ||||
-rw-r--r-- | src/hooks/dhcp/user_chk/subnet_select_co.cc | 42 | ||||
-rw-r--r-- | src/hooks/dhcp/user_chk/user_chk.h | 17 |
5 files changed, 147 insertions, 52 deletions
diff --git a/src/hooks/dhcp/user_chk/load_unload.cc b/src/hooks/dhcp/user_chk/load_unload.cc index fc97de70b9..58ef404366 100644 --- a/src/hooks/dhcp/user_chk/load_unload.cc +++ b/src/hooks/dhcp/user_chk/load_unload.cc @@ -44,6 +44,12 @@ const char* query_user_id_label = "query_user_id_label"; /// @brief Text label of registered user pointer in callout context const char* registered_user_label = "registered_user"; +/// @brief Text id used to identify the default IPv4 user in the registry +const char* default_user4_id_str = "00000000"; + +/// @brief Text id used to identify the default IPv6 user in the registry +const char *default_user6_id_str = "00000000"; + // Functions accessed by the hooks framework use C linkage to avoid the name // mangling that accompanies use of the C++ compiler as well as to avoid // issues related to namespaces. diff --git a/src/hooks/dhcp/user_chk/pkt_receive_co.cc b/src/hooks/dhcp/user_chk/pkt_receive_co.cc index daa0018130..d7814a3aad 100644 --- a/src/hooks/dhcp/user_chk/pkt_receive_co.cc +++ b/src/hooks/dhcp/user_chk/pkt_receive_co.cc @@ -31,8 +31,14 @@ extern "C" { /// @brief This callout is called at the "pkt4_receive" hook. /// -/// This function searches the UserRegistry for the client indicated by the -/// inbound IPv4 DHCP packet. If the client is found @todo +/// This function determines if the DHCP client identified by the inbound +/// DHCP query packet is in the user registry. +/// Upon entry, the registry is refreshed. Next the hardware address is +/// extracted from query and saved to the context as the "query_user_id". +/// This id is then used to search the user registry. The resultant UserPtr +/// whether the user is found or not, is saved to the callout context as +/// "registered_user". This makes the registered user, if not null, available +/// to subsequent callouts. /// /// @param handle CalloutHandle which provides access to context. /// @@ -53,17 +59,17 @@ int pkt4_receive(CalloutHandle& handle) { handle.getArgument("query4", query); HWAddrPtr hwaddr = query->getHWAddr(); - // Store the id we search with. + // Store the id we search with so it is available down the road. handle.setContext(query_user_id_label, hwaddr); // Look for the user in the registry. UserPtr registered_user = user_registry->findUser(*hwaddr); - // store user regardless, empty user pointer means non-found - // cheaper than exception throw overhead + // Store user regardless. Empty user pointer means non-found. It is + // cheaper to fetch it and test it, than to use an exception throw. handle.setContext(registered_user_label, registered_user); std::cout << "DHCP UserCheckHook : pkt4_receive user : " - << hwaddr->toText() << " is " + << hwaddr->toText() << " is " << (registered_user ? " registered" : " not registered") << std::endl; } catch (const std::exception& ex) { @@ -77,8 +83,14 @@ int pkt4_receive(CalloutHandle& handle) { /// @brief This callout is called at the "pkt6_receive" hook. /// -/// This function searches the UserRegistry for the client indicated by the -/// inbound IPv6 DHCP packet. If the client is found @todo +/// This function determines if the DHCP client identified by the inbound +/// DHCP query packet is in the user registry. +/// Upon entry, the registry is refreshed. Next the DUID is extracted from +/// query and saved to the context as the "query_user_id". This id is then +/// used to search the user registry. The resultant UserPtr whether the user +/// is found or not, is saved to the callout context as "registered_user". +/// This makes the registered user, if not null, available to subsequent +/// callouts. /// /// @param handle CalloutHandle which provides access to context. /// @@ -106,17 +118,17 @@ int pkt6_receive(CalloutHandle& handle) { } DuidPtr duid = DuidPtr(new DUID(opt_duid->getData())); - // Store the id we search with. + // Store the id we search with so it is available down the road. handle.setContext(query_user_id_label, duid); // Look for the user in the registry. UserPtr registered_user = user_registry->findUser(*duid); - // store user regardless, empty user pointer means non-found - // cheaper than exception throw overhead + // Store user regardless. Empty user pointer means non-found. It is + // cheaper to fetch it and test it, than to use an exception throw. handle.setContext(registered_user_label, registered_user); std::cout << "DHCP UserCheckHook : pkt6_receive user : " - << duid->toText() << " is " + << duid->toText() << " is " << (registered_user ? " registered" : " not registered") << std::endl; } catch (const std::exception& ex) { diff --git a/src/hooks/dhcp/user_chk/pkt_send_co.cc b/src/hooks/dhcp/user_chk/pkt_send_co.cc index c6147d572a..3f49a6d0bb 100644 --- a/src/hooks/dhcp/user_chk/pkt_send_co.cc +++ b/src/hooks/dhcp/user_chk/pkt_send_co.cc @@ -46,10 +46,10 @@ extern std::string getAddrStrIA_PD(OptionPtr options); extern bool checkIAStatus(boost::shared_ptr<Option6IA>& ia_opt); extern void add4Options(Pkt4Ptr& response, const UserPtr& user); -extern void add4Option(Pkt4Ptr& response, uint8_t opt_code, +extern void add4Option(Pkt4Ptr& response, uint8_t opt_code, std::string& opt_value); extern void add6Options(Pkt6Ptr& response, const UserPtr& user); -extern void add6Option(OptionPtr& vendor, uint8_t opt_code, +extern void add6Option(OptionPtr& vendor, uint8_t opt_code, std::string& opt_value); extern const UserPtr& getDefaultUser4(); extern const UserPtr& getDefaultUser6(); @@ -57,17 +57,17 @@ extern const UserPtr& getDefaultUser6(); /// @brief This callout is called at the "pkt4_send" hook. /// /// This function generates the user check outcome and adds vendor options -/// to the IPv4 respons packet based on whether the user is registered or not. +/// to the IPv4 response packet based on whether the user is registered or not. /// -/// It retrieves a pointer to the registered user from the callout context. +/// It retrieves a pointer to the registered user from the callout context. /// This value should have been set upstream. If the registered user pointer /// is non-null (i.e the user is registered), then a registered user outcome /// is recorded in the outcome output and the vendor properties are altered -/// based upon this user's properitees. +/// based upon this user's properties. /// /// A null value means the user is not registered and a unregistered user -/// outcome is recorded in the outcome output and the vendor properites -/// are altered based upon the default IPv4 user in the registry (if defined). +/// outcome is recorded in the outcome output and the vendor properties +/// are altered based upon the default IPv4 user in the registry (if defined). /// /// @param handle CalloutHandle which provides access to context. /// @@ -136,8 +136,8 @@ int pkt4_send(CalloutHandle& handle) { /// - DHO_BOOT_FILE_NAME from user property "bootfile" /// - DHO_TFTP_SERVER_NAME from user property "tftp_server" /// -/// @param response IPv4 reponse packet -/// @param user User from whom properties are sourced +/// @param response IPv4 response packet +/// @param user User from whom properties are sourced void add4Options(Pkt4Ptr& response, const UserPtr& user) { // If user is null, do nothing. if (!user) { @@ -190,17 +190,17 @@ void add4Option(Pkt4Ptr& response, uint8_t opt_code, std::string& opt_value) { /// @brief This callout is called at the "pkt6_send" hook. /// /// This function generates the user check outcome and adds vendor options -/// to the IPv6 respons packet based on whether the user is registered or not. +/// to the IPv6 response packet based on whether the user is registered or not. /// -/// It retrieves a pointer to the registered user from the callout context. +/// It retrieves a pointer to the registered user from the callout context. /// This value should have been set upstream. If the registered user pointer /// is non-null (i.e the user is registered), then a registered user outcome /// is recorded in the outcome output and the vendor properties are altered -/// based upon this user's properitees. +/// based upon this user's properties. /// /// A null value means the user is not registered and a unregistered user -/// outcome is recorded in the outcome output and the vendor properites -/// are altered based upon the default IPv6 user in the registry (if defined). +/// outcome is recorded in the outcome output and the vendor properties +/// are altered based upon the default IPv6 user in the registry (if defined). /// @param handle CalloutHandle which provides access to context. /// /// @return 0 upon success, non-zero otherwise. @@ -273,7 +273,7 @@ int pkt6_send(CalloutHandle& handle) { /// - DOCSIS3_V6_TFTP_SERVERS from user property "tftp_server" /// /// @param response IPv5 reponse packet -/// @param user User from whom properties are sourced +/// @param user User from whom properties are sourced void add6Options(Pkt6Ptr& response, const UserPtr& user) { if (!user) { return; @@ -284,7 +284,7 @@ void add6Options(Pkt6Ptr& response, const UserPtr& user) { OptionPtr vendor = response->getOption(D6O_VENDOR_OPTS); if (!vendor) { std::cout << "DHCP UserCheckHook : add6Options " - << "no vendor options punt" << std::endl; + << "response has no vendor option to update" << std::endl; return; } @@ -327,7 +327,7 @@ void add6Option(OptionPtr& vendor, uint8_t opt_code, std::string& opt_value) { /// @brief Adds an entry to the end of the user check outcome file. /// -/// @todo This ought to be replaced with an abstract output similiar to +/// @todo This ought to be replaced with an abstract output similar to /// UserDataSource to allow greater flexibility. /// /// Each user entry is written in an ini-like format, with one name-value pair @@ -388,6 +388,15 @@ void generate_output_record(const std::string& id_type_str, } /// @brief Stringify the lease address or prefix IPv6 response packet +/// +/// Converts the lease value, either an address or a prefix, into a string +/// suitable for the user check outcome output. +/// +/// @param response IPv6 response packet from which to extract the lease value. +/// +/// @return A string containing the lease value. +/// @throw isc::BadValue if the response contains neither an IA_NA nor IA_PD +/// option. std::string getV6AddrStr (Pkt6Ptr response) { OptionPtr tmp = response->getOption(D6O_IA_NA); if (tmp) { @@ -404,6 +413,16 @@ std::string getV6AddrStr (Pkt6Ptr response) { } /// @brief Stringify the lease address in an D6O_IA_NA option set +/// +/// Converts the IA_NA lease address into a string suitable for the user check +/// outcome output. +/// +/// @param options pointer to the Option6IA instance from which to extract the +/// lease address. +/// +/// @return A string containing the lease address. +/// +/// @throw isc::BadValue if the lease address cannot be extracted from options. std::string getAddrStrIA_NA(OptionPtr options) { boost::shared_ptr<Option6IA> ia = boost::dynamic_pointer_cast<Option6IA>(options); @@ -432,20 +451,34 @@ std::string getAddrStrIA_NA(OptionPtr options) { return (addr.toText()); } -/// @brief Stringify the delegated prefix in an D6O_IA_DP option set +/// @brief Stringify the lease prefix in an D6O_IA_PD option set +/// +/// Converts the IA_PD lease prefix into a string suitable for the user check +/// outcome output. +/// +/// @param options pointer to the Option6IA instance from which to extract the +/// lease prefix. +/// +/// @return A string containing lease prefix +/// +/// @throw isc::BadValue if the prefix cannot be extracted from options. std::string getAddrStrIA_PD(OptionPtr options) { boost::shared_ptr<Option6IA> ia = boost::dynamic_pointer_cast<Option6IA>(options); + // Make sure we have an IA_PD option. if (!ia) { isc_throw (isc::BadValue, "D6O_IA_PD option invalid"); } - // If status indicates a failure return a blank string. + // Check the response for success status. If it isn't a success response + // there will not be a lease prefix value which is denoted by returning + // an empty string. if (!checkIAStatus(ia)) { return (std::string("")); } + // Get the prefix option the IA_PD option. options = ia->getOption(D6O_IAPREFIX); if (!options) { isc_throw(isc::BadValue, "D60_IAPREFIX option is missing"); @@ -457,15 +490,26 @@ std::string getAddrStrIA_PD(OptionPtr options) { isc_throw (isc::BadValue, "D6O_IA_PD addr option bad"); } + // Get the address and prefix length values. isc::asiolink::IOAddress addr = addr_option->getAddress(); uint8_t prefix_len = addr_option->getLength(); + // Build the output string and return it. stringstream buf; buf << addr.toText() << "/" << static_cast<int>(prefix_len); return (buf.str()); } /// @brief Tests given IA option set for successful status. +/// +/// This function is used to determine if the given Option6IA represents +/// a successful lease operation. If it contains no status option or a status +/// option of 0 (which is defined to mean success), then the option represents +/// success and should contain a lease value (address or prefix). +/// +/// @param ia pointer to the Option6IA to test +/// +/// @return True if the option represents success, false otherwise. bool checkIAStatus(boost::shared_ptr<Option6IA>& ia) { OptionCustomPtr status = boost::dynamic_pointer_cast @@ -484,12 +528,24 @@ bool checkIAStatus(boost::shared_ptr<Option6IA>& ia) { return (true); } +/// @brief Fetches the default IPv4 user from the registry. +/// +/// The default user may be used to provide default property values. +/// +/// @return A pointer to the IPv4 user or null if not defined. const UserPtr& getDefaultUser4() { - return (user_registry->findUser(UserId(UserId::HW_ADDRESS, "00000000"))); + return (user_registry->findUser(UserId(UserId::HW_ADDRESS, + default_user4_id_str))); } +/// @brief Fetches the default IPv6 user from the registry. +/// +/// The default user may be used to provide default property values. +/// +/// @return A pointer to the IPv6 user or null if not defined. const UserPtr& getDefaultUser6() { - return (user_registry->findUser(UserId(UserId::DUID, "0000000000"))); + return (user_registry->findUser(UserId(UserId::DUID, + default_user6_id_str))); } } // end extern "C" diff --git a/src/hooks/dhcp/user_chk/subnet_select_co.cc b/src/hooks/dhcp/user_chk/subnet_select_co.cc index 24c1dcee44..8a2d2e0cfc 100644 --- a/src/hooks/dhcp/user_chk/subnet_select_co.cc +++ b/src/hooks/dhcp/user_chk/subnet_select_co.cc @@ -32,14 +32,16 @@ extern "C" { /// @brief This callout is called at the "subnet4_select" hook. /// -/// This function searches the UserRegistry for the client indicated by the -/// inbound IPv4 DHCP packet. If the client is found in the registry output -/// the generate outcome record and return. +/// This function alters the selected subnet based upon whether or not the +/// requesting DHCP client is a "registered user". It fetches a pointer to +/// the registered user from the callout context. This value is presumed to +/// have been set upstream. If it is non-null that it points to the client's +/// user entry in the UserRegistry. If it is null, the client is not +/// registered. /// -/// If the client is not found in the registry replace the selected subnet -/// with the restricted access subnet, then generate the outcome record and -/// return. By convention, it is assumed that last subnet in the list of -/// available subnets is the restricted access subnet. +/// If the client is registered, then replace the selected subnet with the +/// restricted access subnet. By convention, it is assumed that last subnet in +/// the list of available subnets is the restricted access subnet. /// /// @param handle CalloutHandle which provides access to context. /// @@ -55,8 +57,8 @@ int subnet4_select(CalloutHandle& handle) { // Get subnet collection. If it's empty just bail nothing to do. const isc::dhcp::Subnet4Collection *subnets = NULL; handle.getArgument("subnet4collection", subnets); - if (subnets->size() == 0) { - return 0; + if (subnets->empty()) { + return (0); } // Get registered_user pointer. @@ -85,14 +87,16 @@ int subnet4_select(CalloutHandle& handle) { /// @brief This callout is called at the "subnet6_select" hook. /// -/// This function searches the UserRegistry for the client indicated by the -/// inbound IPv6 DHCP packet. If the client is found in the registry generate -/// the outcome record and return. +/// This function alters the selected subnet based upon whether or not the +/// requesting DHCP client is a "registered user". It fetches a pointer to +/// the registered user from the callout context. This value is presumed to +/// have been set upstream. If it is non-null that it points to the client's +/// user entry in the UserRegistry. If it is null, the client is not +/// registered. /// -/// If the client is not found in the registry replace the selected subnet -/// with the restricted access subnet, then generate the outcome record and -/// return. By convention, it is assumed that last subnet in the list of -/// available subnets is the restricted access subnet. +/// If the client is registered, then replace the selected subnet with the +/// restricted access subnet. By convention, it is assumed that last subnet in +/// the list of available subnets is the restricted access subnet. /// /// @param handle CalloutHandle which provides access to context. /// @@ -108,11 +112,11 @@ int subnet6_select(CalloutHandle& handle) { // Get subnet collection. If it's empty just bail nothing to do. const isc::dhcp::Subnet6Collection *subnets = NULL; handle.getArgument("subnet6collection", subnets); - if (subnets->size() == 0) { - return 0; + if (subnets->empty()) { + return (0); } - // Get registered_user pointer. + // Get registered_user pointer. UserPtr registered_user; handle.getContext(registered_user_label, registered_user); diff --git a/src/hooks/dhcp/user_chk/user_chk.h b/src/hooks/dhcp/user_chk/user_chk.h index a077c7675b..d19a7c55a2 100644 --- a/src/hooks/dhcp/user_chk/user_chk.h +++ b/src/hooks/dhcp/user_chk/user_chk.h @@ -20,11 +20,28 @@ using namespace std; +/// @brief Pointer to the registry instance. extern UserRegistryPtr user_registry; + +/// @brief Output filestream for recording user check outcomes. extern std::fstream user_chk_output; + +/// @brief User registry input file name. extern const char* registry_fname; + +/// @brief User check outcome file name. extern const char* user_chk_output_fname; + +/// @brief Text label of user id in the inbound query in callout context extern const char* query_user_id_label; + +/// @brief Text label of registered user pointer in callout context extern const char* registered_user_label; +/// @brief Text id used to identify the default IPv4 user in the registry +extern const char* default_user4_id_str; + +/// @brief Text id used to identify the default IPv6 user in the registry +extern const char *default_user6_id_str; + #endif |