Browse Source

[3186] user_chk hook selects subnet6 based on user_registry

Interrim checkin. Subnet6 selection is working and user check outcome is
being written out to file, "/tmp/user_check_output.txt".
Thomas Markwalder 11 years ago
parent
commit
bd647c2a98
2 changed files with 90 additions and 33 deletions
  1. 39 10
      src/hooks/dhcp/user_chk/load_unload.cc
  2. 51 23
      src/hooks/dhcp/user_chk/subnet_select_co.cc

+ 39 - 10
src/hooks/dhcp/user_chk/load_unload.cc

@@ -17,31 +17,60 @@
 #include <user_registry.h>
 #include <user_file.h>
 
+#include <iostream>
+#include <fstream>
+
 using namespace isc::hooks;
 
 UserRegistryPtr user_registry;
+std::fstream user_chk_output;
+const char* registry_fname = "/tmp/user_registry.txt";
+const char* user_chk_output_fname = "/tmp/user_check_output.txt";
 
 extern "C" {
 
 int load(LibraryHandle&) {
-    // @todo what about exception handling
 
-    // Instantiate the registry.
-    user_registry.reset(new UserRegistry());
+    // non-zero indicates an error.
+    int ret_val = 0;
+    try {
+        // Instantiate the registry.
+        user_registry.reset(new UserRegistry());
 
-    // Create the data source.
-    UserDataSourcePtr user_file(new UserFile("/tmp/user_registry.txt"));
+        // Create the data source.
+        UserDataSourcePtr user_file(new UserFile(registry_fname));
 
-    // Set the registry's data source
-    user_registry->setSource(user_file);
+        // Set the registry's data source
+        user_registry->setSource(user_file);
 
-    // Do an initial load of the registry.
-    user_registry->refresh();
-    return (0);
+        // Do an initial load of the registry.
+        user_registry->refresh();
+
+        // Open up the output file for user_chk results.
+        user_chk_output.open(user_chk_output_fname,
+                     std::fstream::out | std::fstream::app);
+
+        if (!user_chk_output) {
+            std::cout << "UserCheckHook: cannot open user check output file: "
+                      << user_chk_output_fname << std::endl;
+            ret_val = 1;
+        }
+    }
+    catch (const std::exception& ex) {
+        std::cout << "UserCheckHook: loading user_chk hook lib failed:"
+                  << ex.what() << std::endl;
+        ret_val = 1;
+    }
+
+    return (ret_val);
 }
 
 int unload() {
     user_registry.reset();
+    if (user_chk_output.is_open()) {
+        user_chk_output.close();
+    }
+
     return (0);
 }
 

+ 51 - 23
src/hooks/dhcp/user_chk/subnet_select_co.cc

@@ -5,20 +5,41 @@
 #include <dhcpsrv/subnet.h>
 #include <user_registry.h>
 
-extern UserRegistryPtr user_registry;
-
+#include <fstream>
 #include <string>
 
 using namespace isc::dhcp;
 using namespace isc::hooks;
 using namespace std;
 
+extern UserRegistryPtr user_registry;
+extern std::fstream user_chk_output;
+extern const char* registry_fname;
+extern const char* user_chk_output_fname;
+
+
 extern "C" {
 
+
+void generate_output_record(const std::string& id_type_str,
+                            const std::string& id_val_str,
+                            const std::string& subnet_str,
+                            const bool& registered)
+{
+    user_chk_output << "id_type=" << id_type_str << std::endl
+                    << "client=" << id_val_str << std::endl
+                    << "subnet=" << subnet_str << std::endl
+                    << "registered=" << (registered ? "yes" : "no")
+                    << std::endl;
+
+    flush(user_chk_output);
+}
+
 // This callout is called at the "subnet4_select" hook.
 int subnet4_select(CalloutHandle& handle) {
     if (!user_registry) {
-        std::cout << "UserRegistry is null!" << std::endl;
+        std::cout << "UserCheckHook: UserRegistry is null!" << std::endl;
+        return (1);
     }
 
     try {
@@ -35,31 +56,35 @@ int subnet4_select(CalloutHandle& handle) {
         if (registered_user) {
             // User is in the registry, so leave the pre-selected
             // subnet alone.
-            std::cout << "DHCP4 User is registered! :"
-                      << registered_user->getUserId() << std::endl;
+            Subnet4Ptr subnet;
+            handle.getArgument("subnet4", subnet);
+            generate_output_record("mac", hwaddr->toText(), subnet->toText(),
+                                   true);
         } else {
             // User is not in the registry, so assign them to
             // the last subnet in the collection.  By convention
             // we are assuming this is the restricted subnet.
-            std::cout << "DHCP4 User is NOT registered! :"
-                     << hwaddr->toText() << std::endl;
             const isc::dhcp::Subnet4Collection *subnets = NULL;
             handle.getArgument("subnet4collection", subnets);
-            handle.setArgument("subnet4", subnets->back());
+            Subnet4Ptr subnet = subnets->back();
+            handle.setArgument("subnet4", subnet);
+            generate_output_record("mac", hwaddr->toText(), subnet->toText(),
+                                   false);
         }
     } catch (const std::exception& ex) {
-        std::cout << "Exception in subnet4_select callout:" << ex.what()
-                  << std::endl;
+        std::cout << "UserCheckHook: Exception in subnet4_select callout:"
+                  << ex.what() << std::endl;
 
+        return (1);
     }
 
     return (0);
 }
-
 // This callout is called at the "subnet6_select" hook.
 int subnet6_select(CalloutHandle& handle) {
     if (!user_registry) {
-        std::cout << "UserRegistry is null!" << std::endl;
+        std::cout << "UserCheckHook: UserRegistry is null!" << std::endl;
+        return (1);
     }
 
     try {
@@ -72,33 +97,36 @@ int subnet6_select(CalloutHandle& handle) {
 
         DuidPtr duid;
         OptionPtr opt_duid = query->getOption(D6O_CLIENTID);
-        if (opt_duid) {
-            duid = DuidPtr(new DUID(opt_duid->getData()));
-        } else {
+        if (!opt_duid) {
             std::cout << "DHCP6 query is missing DUID" << std::endl;
+            return (1);
         }
 
+        duid = DuidPtr(new DUID(opt_duid->getData()));
+
         // Look for the user.
         UserPtr registered_user = user_registry->findUser(*duid);
         if (registered_user) {
             // User is in the registry, so leave the pre-selected
             // subnet alone.
-            std::cout << "DHCP6 User is registered! :"
-                      << registered_user->getUserId() << std::endl;
+            Subnet6Ptr subnet;
+            handle.getArgument("subnet6", subnet);
+            generate_output_record("duid", duid->toText(), subnet->toText(),
+                                   true);
         } else {
             // User is not in the registry, so assign them to
             // the last subnet in the collection.  By convention
             // we are assuming this is the restricted subnet.
-            std::cout << "DHCP6 User is NOT registered! :"
-                     << duid->toText() << std::endl;
             const isc::dhcp::Subnet6Collection *subnets = NULL;
             handle.getArgument("subnet6collection", subnets);
-            handle.setArgument("subnet6", subnets->back());
+            Subnet6Ptr subnet = subnets->back();
+            handle.setArgument("subnet6", subnet);
+            generate_output_record("duid", duid->toText(), subnet->toText(),
+                                   false);
         }
     } catch (const std::exception& ex) {
-        std::cout << "Exception in subnet6_select callout:" << ex.what()
-                  << std::endl;
-
+        std::cout << "UserCheckHook: Exception in subnet6_select callout:"                        << ex.what() << std::endl;
+        return (1);
     }
 
     return (0);