summaryrefslogtreecommitdiffstats
path: root/src/hooks
diff options
context:
space:
mode:
authorThomas Markwalder <tmark@isc.org>2013-10-28 16:37:53 +0100
committerThomas Markwalder <tmark@isc.org>2013-10-28 16:37:53 +0100
commit3b1b5032e2afd07bf7d947e185b59a04d9805e08 (patch)
tree4b01eb8cd77a1d55ebc7205b9f9f8366a8c78a58 /src/hooks
parent[3207] Added support for default users and delimited user id input (diff)
downloadkea-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.cc6
-rw-r--r--src/hooks/dhcp/user_chk/pkt_receive_co.cc36
-rw-r--r--src/hooks/dhcp/user_chk/pkt_send_co.cc98
-rw-r--r--src/hooks/dhcp/user_chk/subnet_select_co.cc42
-rw-r--r--src/hooks/dhcp/user_chk/user_chk.h17
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