Adding options to disable/enable firewall policy and choose MAC/IP translation methods
[iot2.git] / iotjava / iotruntime / master / IoTMaster.java
index ce99125e4f947f06ba975df66a253f463fa3ae54..15948bf633de21d17394055eccc2dcbf9bfc6953 100644 (file)
@@ -40,7 +40,7 @@ import static java.lang.Math.toIntExact;
  * @version     1.0
  * @since       2016-06-16
  */
-public class IoTMaster {
+public final class IoTMaster {
 
        /**
         * IoTMaster class properties
@@ -51,6 +51,7 @@ public class IoTMaster {
        private CommunicationHandler commHan;
        private LoadBalancer lbIoT;
        private RouterConfig routerConfig;
+       private ProcessJailConfig processJailConfig;
        private ObjectInitHandler objInitHand;
        private ObjectAddressInitHandler objAddInitHand;
        private String[] strObjectNames;
@@ -101,6 +102,9 @@ public class IoTMaster {
        private static String STR_LANGUAGE_CONTROLLER;
        private static String STR_SKEL_CLASS_SUFFIX;
        private static String STR_STUB_CLASS_SUFFIX;
+       private static String STR_ACTIVATE_SANDBOXING;
+       private static String STR_POLICY_ON;
+       private static String STR_MAC_TO_IP_TRANSLATION;
        private static boolean BOOL_VERBOSE;
 
        /**
@@ -112,6 +116,7 @@ public class IoTMaster {
        private static final String STR_CFG_FILE_EXT = ".config";
        private static final String STR_CLS_FILE_EXT = ".class";
        private static final String STR_JAR_FILE_EXT = ".jar";
+       private static final String STR_MAC_POLICY_EXT = ".tomoyo.pol"; 
        private static final String STR_SHELL_FILE_EXT = ".sh";
        private static final String STR_SO_FILE_EXT = ".so";
        private static final String STR_ZIP_FILE_EXT = ".zip";
@@ -124,6 +129,7 @@ public class IoTMaster {
        private static final String STR_INT_STUB_CLS_CFG = "INTERFACE_STUB_CLASS";
        private static final String STR_FILE_TRF_CFG = "ADDITIONAL_ZIP_FILE";
        private static final String STR_LANGUAGE = "LANGUAGE";
+       private static final String STR_ADD_MAC_POL = "ADDITIONAL_MAC_POLICY";
        private static final String STR_YES = "Yes";
        private static final String STR_NO = "No";
        private static final String STR_JAVA = "Java";
@@ -133,8 +139,12 @@ public class IoTMaster {
        private static final String STR_IOTSLAVE_CPP = "./IoTSlave.o";
        private static final String STR_SHELL_HEADER = "#!/bin/sh";
        private static final String STR_JAVA_PATH = "/usr/bin/java";
+       private static final String STR_MAC_POL_PATH = "tomoyo/";
+        private static final String STR_TMP = "tmp";
+        private static final String STR_ARP = "arp";
 
        private static int INT_SIZE = 4;        // send length in the size of integer (4 bytes)
+       private static final int INT_DNS_PORT = 53;
 
        /**
         * Runtime class name constants - not to be configured by users
@@ -155,6 +165,7 @@ public class IoTMaster {
                commHan = null;
                lbIoT = null;
                routerConfig = null;
+               processJailConfig = null;
                objInitHand = null;
                objAddInitHand = null;
                strObjectNames = argObjNms;
@@ -193,6 +204,9 @@ public class IoTMaster {
                STR_JVM_INIT_HEAP_SIZE = null;
                STR_JVM_MAX_HEAP_SIZE = null;
                STR_LANGUAGE_CONTROLLER = null;
+               STR_ACTIVATE_SANDBOXING = null;
+               STR_POLICY_ON = null;
+               STR_MAC_TO_IP_TRANSLATION = null;
                BOOL_VERBOSE = false;
        }
 
@@ -207,7 +221,15 @@ public class IoTMaster {
                lbIoT = new LoadBalancer(BOOL_VERBOSE);
                lbIoT.setupLoadBalancer();
                routerConfig = new RouterConfig();
-               routerConfig.getAddressList(STR_ROUTER_ADD);
+               // Get MAC to IP translation either from /tmp/dhcp.leases or arp command
+               if (STR_MAC_TO_IP_TRANSLATION.equals(STR_TMP))
+                       routerConfig.getAddressListTmp(STR_ROUTER_ADD);
+               else if (STR_MAC_TO_IP_TRANSLATION.equals(STR_ARP))
+                       routerConfig.getAddressListArp(STR_ROUTER_ADD);
+               else
+                       throw new Error("IoTMaster: Unknown value for STR_MAC_TO_IP_TRANSLATION: " + STR_MAC_TO_IP_TRANSLATION);
+               processJailConfig = new ProcessJailConfig();
+               //processJailConfig.setAddressListObject(routerConfig.getAddressListObject());
                objInitHand = new ObjectInitHandler(BOOL_VERBOSE);
                objAddInitHand = new ObjectAddressInitHandler(BOOL_VERBOSE);
                mapClassNameToCrim = new HashMap<String,Object>();
@@ -270,6 +292,9 @@ public class IoTMaster {
                STR_JVM_MAX_HEAP_SIZE = prop.getProperty("JVM_MAX_HEAP_SIZE");
                STR_SKEL_CLASS_SUFFIX = prop.getProperty("SKEL_CLASS_SUFFIX");
                STR_STUB_CLASS_SUFFIX = prop.getProperty("STUB_CLASS_SUFFIX");
+               STR_ACTIVATE_SANDBOXING = prop.getProperty("ACTIVATE_SANDBOXING");
+               STR_POLICY_ON = prop.getProperty("POLICY_ON");
+               STR_MAC_TO_IP_TRANSLATION = prop.getProperty("MAC_TO_IP_TRANSLATION");
                if(prop.getProperty("VERBOSE").equals(STR_YES)) {
                        BOOL_VERBOSE = true;
                }
@@ -294,6 +319,9 @@ public class IoTMaster {
                RuntimeOutput.print("STR_JVM_MAX_HEAP_SIZE=" + STR_JVM_MAX_HEAP_SIZE, BOOL_VERBOSE);
                RuntimeOutput.print("STR_SKEL_CLASS_SUFFIX=" + STR_SKEL_CLASS_SUFFIX, BOOL_VERBOSE);
                RuntimeOutput.print("STR_STUB_CLASS_SUFFIX=" + STR_STUB_CLASS_SUFFIX, BOOL_VERBOSE);
+               RuntimeOutput.print("STR_ACTIVATE_SANDBOXING=" + STR_ACTIVATE_SANDBOXING, BOOL_VERBOSE);
+               RuntimeOutput.print("STR_POLICY_ON=" + STR_POLICY_ON, BOOL_VERBOSE);
+               RuntimeOutput.print("STR_MAC_TO_IP_TRANSLATION=" + STR_MAC_TO_IP_TRANSLATION, BOOL_VERBOSE);
                RuntimeOutput.print("BOOL_VERBOSE=" + BOOL_VERBOSE, BOOL_VERBOSE);
                RuntimeOutput.print("IoTMaster: Information extracted successfully!", BOOL_VERBOSE);
        }
@@ -405,6 +433,7 @@ public class IoTMaster {
 
                // Get information from the set
                List<Object[]> listObject = objAddInitHand.getFields(strFieldIdentifier);
+        RuntimeOutput.print("IoTMaster: DEBUG: Getting into instrumentIoTSetDevice!", BOOL_VERBOSE);
                // Create a new IoTSet
                if(strLanguage.equals(STR_JAVA)) {
                        Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName);
@@ -507,7 +536,7 @@ public class IoTMaster {
                RuntimeOutput.print("IoTMaster: Number of rows for IoTZigbeeAddress: " + iRows, BOOL_VERBOSE);
 
                // TODO: DEBUG!!!
-               System.out.println("\n\n DEBUG: InstrumentZigbeeDevice: Object Name: " + strObjName);
+               System.out.println("\n\nDEBUG: InstrumentZigbeeDevice: Object Name: " + strObjName);
                System.out.println("DEBUG: InstrumentZigbeeDevice: Port number: " + commHan.getComPort(strZigbeeGWAddressKey));
                System.out.println("DEBUG: InstrumentZigbeeDevice: Device address: " + strZigbeeGWAddress + "\n\n");
 
@@ -577,10 +606,11 @@ public class IoTMaster {
         * A private method to instrument an object on a specific machine and setting up policies
         *
         * @params  strFieldObjectID              String field object ID
+        * @params  strObjControllerName          String object controller name
         * @params  strLanguage                           String language
         * @return  void
         */
-       private void instrumentObject(String strFieldObjectID, String strLanguage) throws IOException {
+       private void instrumentObject(String strFieldObjectID, String strObjControllerName, String strLanguage) throws IOException {
 
                // Extract the interface name for RMI
                // e.g. ProximitySensorInterface, TempSensorInterface, etc.
@@ -625,6 +655,22 @@ public class IoTMaster {
                                strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
                        routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd,
                                strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
+                       // Configure MAC policies for objects
+                       //String strFileName = STR_MAC_POL_PATH + strObjClassName + STR_MAC_POLICY_EXT;
+                       String strFileName = STR_MAC_POL_PATH + STR_JAVA + STR_MAC_POLICY_EXT;
+                       if (STR_ACTIVATE_SANDBOXING.equals("Yes")) {
+                               processJailConfig.configureProcessJailDeviceDriverPolicies(strIoTSlaveObjectHostAdd, strObjName, strObjClassName,
+                                       strFileName, strIoTMasterHostAdd, commHan.getComPort(strObjName), commHan.getRMIRegPort(strObjName), 
+                                       commHan.getRMIStubPort(strObjName));
+                   // Check for additional MAC policy
+                   String strMACConfigPath = STR_IOT_CODE_PATH + strObjClassName + "/";
+                   String strCfgFile = strMACConfigPath + strObjClassName + STR_CFG_FILE_EXT;
+                       String strAddMACPolicy = parseConfigFile(strCfgFile, STR_ADD_MAC_POL);
+                   if (strAddMACPolicy != null && strAddMACPolicy.equals("Yes"))
+                       processJailConfig.combineAdditionalMACPolicy(strMACConfigPath, strObjClassName, strIoTSlaveObjectHostAdd);
+                               processJailConfig.configureProcessJailContRMIPolicies(strObjControllerName, strIoTSlaveObjectHostAdd, 
+                                       commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName));
+                       }
                        // Instrument the IoTSet declarations inside the class file
                        instrumentObjectIoTSet(strFieldObjectID, strLanguage);
                }
@@ -715,6 +761,9 @@ public class IoTMaster {
                                routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, STR_TCP_PROTOCOL, iDestDeviceDriverPort);
                                routerConfig.configureRouterHTTPPolicies(STR_ROUTER_ADD, strIoTSlaveObjectHostAdd, strDeviceAddress);
                                routerConfig.configureHostHTTPPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress);
+                               // Configure MAC policies
+                               if (STR_ACTIVATE_SANDBOXING.equals("Yes"))
+                                       processJailConfig.configureProcessJailGWDevicePolicies(strIoTSlaveObjectHostAdd, STR_ROUTER_ADD, strDeviceAddress, INT_DNS_PORT);
                        } else {
                                // Other port numbers...
                                commHan.addDevicePort(iDestDeviceDriverPort);
@@ -722,6 +771,10 @@ public class IoTMaster {
                                        commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort);
                                routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveObjectHostAdd, strDeviceAddress, strProtocol, 
                                        commHan.getComPort(strDeviceAddressKey), iDestDeviceDriverPort);
+                               // Configure MAC policies
+                               if (STR_ACTIVATE_SANDBOXING.equals("Yes"))
+                                       processJailConfig.configureProcessJailDevicePolicies(strIoTSlaveObjectHostAdd, strProtocol,
+                                               commHan.getComPort(strDeviceAddressKey), strDeviceAddress, iDestDeviceDriverPort);
                        }
                }
        }
@@ -735,7 +788,7 @@ public class IoTMaster {
         * @return  void
         */
        private void setRouterPolicyIoTSetAddress(String strFieldIdentifier, Map.Entry<String,Object> map, 
-               String strHostAddress) {
+               String strHostAddress, String strControllerName) {
 
                // Get information from the set
                SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
@@ -748,6 +801,13 @@ public class IoTMaster {
                        // Get device address
                        String strAddress = (String) arrFieldValues[0];
                        // Setting up router policies for HTTP/HTTPs
+                       if (STR_ACTIVATE_SANDBOXING.equals("Yes")) {
+                               if (strControllerName != null) {
+                                       processJailConfig.configureProcessJailInetAddressPolicies(strControllerName, STR_ROUTER_ADD, strAddress);
+                               } else {
+                                       processJailConfig.configureProcessJailInetAddressPolicies(strHostAddress, STR_ROUTER_ADD, strAddress);
+                               }
+                       }
                        routerConfig.configureRouterHTTPPolicies(STR_ROUTER_ADD, strHostAddress, strAddress);
                        routerConfig.configureHostHTTPPolicies(strHostAddress, strHostAddress, strAddress);
                }
@@ -802,7 +862,7 @@ public class IoTMaster {
                                        setRouterPolicyIoTSetDevice(strFieldIdentifier, map, strIoTSlaveObjectHostAdd);
                                } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) { 
                                // Instrument the IoTAddress
-                                       setRouterPolicyIoTSetAddress(strFieldIdentifier, map, strIoTSlaveObjectHostAdd);
+                                       setRouterPolicyIoTSetAddress(strFieldIdentifier, map, strIoTSlaveObjectHostAdd, null);
                                } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) { 
                                // Instrument the IoTZigbeeAddress - special feature for Zigbee device support
                                        RuntimeOutput.print("IoTMaster: IoTZigbeeAddress found! No router policy is set here..", 
@@ -891,14 +951,6 @@ public class IoTMaster {
         *
         * @return       String
         */
-       /*private String getCmdJavaDriverIoTSlave(String strIoTMasterHostAdd, String strIoTSlaveObjectHostAdd, String strObjName) {
-
-               return STR_SSH + " " + STR_USERNAME + strIoTSlaveObjectHostAdd + " cd " + STR_RUNTIME_DIR + " sudo java " +
-                       STR_CLS_PATH + " " + STR_RMI_PATH + " " + STR_RMI_HOSTNAME +
-                       strIoTSlaveObjectHostAdd + " " + STR_IOT_SLAVE_CLS + " " + strIoTMasterHostAdd + " " +
-                       commHan.getComPort(strObjName) + " " + commHan.getRMIRegPort(strObjName) + " " +
-                       commHan.getRMIStubPort(strObjName) + " >& " + STR_LOG_FILE_PATH + strObjName + ".log &";
-       }*/
        private String getCmdJavaDriverIoTSlave(String strIoTMasterHostAdd, String strIoTSlaveObjectHostAdd, String strObjName) {
 
                // Create an Shell executable
@@ -1057,6 +1109,7 @@ public class IoTMaster {
                                if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) { 
                                // Instrument the normal IoTDeviceAddress
                                        synchronized(this) {
+                                   //RuntimeOutput.print("IoTMaster: DEBUG: Processing " + STR_IOT_DEV_ADD_CLS + "!", BOOL_VERBOSE);
                                                instrumentIoTSetDevice(strFieldIdentifier, strObjName, strFieldName, strIoTSlaveObjectHostAdd, inStream, outStream, strLanguageDriver);
                                        }
                                } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) { 
@@ -1153,7 +1206,7 @@ public class IoTMaster {
         * @params  strLanguage                           String language
         * @return  void
         */
-       private void instrumentIoTSet(Map.Entry<String,Object> map, String strFieldName, String strLanguage) 
+       private void instrumentIoTSet(Map.Entry<String,Object> map, String strFieldName, String strObjControllerName, String strLanguage) 
                throws IOException, ClassNotFoundException, InterruptedException {
                                
                // Get information from the set
@@ -1169,7 +1222,7 @@ public class IoTMaster {
                        String strObjID = setInstrumenter.fieldObjectID(iRow);
                        strObjClassName = setInstrumenter.fieldEntryType(strObjID);
                        // Call the method to create an object
-                       instrumentObject(strObjID, strLanguage);
+                       instrumentObject(strObjID, strObjControllerName, strLanguage);
                        objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
                                strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName), 
                                commHan.getRMIStubPort(strObjName));
@@ -1185,7 +1238,7 @@ public class IoTMaster {
         * @params  strLanguage                           String language
         * @return  void
         */
-       private void instrumentIoTRelation(Map.Entry<String,Object> map, String strFieldName, String strLanguage) 
+       private void instrumentIoTRelation(Map.Entry<String,Object> map, String strFieldName, String strObjControllerName, String strLanguage) 
                throws IOException, ClassNotFoundException, InterruptedException {
 
                        // Get information from the set
@@ -1200,7 +1253,7 @@ public class IoTMaster {
                        String strObjID = relationInstrumenter.firstFieldObjectID(iRow);
                        strObjClassName = relationInstrumenter.firstEntryFieldType(strObjID);
                        // Call the method to create an object
-                       instrumentObject(strObjID, strLanguage);
+                       instrumentObject(strObjID, strObjControllerName, strLanguage);
                        // Get the first object controller host address
                        String strFirstIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
                        objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
@@ -1212,7 +1265,7 @@ public class IoTMaster {
                        strObjID = relationInstrumenter.secondFieldObjectID(iRow);
                        strObjClassName = relationInstrumenter.secondEntryFieldType(strObjID);
                        // Call the method to create an object
-                       instrumentObject(strObjID, strLanguage);
+                       instrumentObject(strObjID, strObjControllerName, strLanguage);
                        // Get the second object controller host address
                        String strSecondIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
                        objInitHand.addSecondObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
@@ -1347,6 +1400,8 @@ public class IoTMaster {
        private void setRouterBasicPolicies(String strRouter) {
 
                String strMonitorHost = routerConfig.getIPFromMACAddress(STR_MONITORING_HOST);
+           routerConfig.initMainPolicy(strRouter);
+           routerConfig.combineRouterPolicies(strRouter);
                routerConfig.configureRouterICMPPolicies(strRouter, strMonitorHost);
                routerConfig.configureRouterDHCPPolicies(strRouter);
                routerConfig.configureRouterDNSPolicies(strRouter);
@@ -1363,6 +1418,8 @@ public class IoTMaster {
        private void setHostBasicPolicies(String strHost) {
 
                String strMonitorHost = routerConfig.getIPFromMACAddress(STR_MONITORING_HOST);
+           routerConfig.initMainPolicy(strHost);
+           routerConfig.combineRouterPolicies(strHost);
                routerConfig.configureHostDHCPPolicies(strHost);
                routerConfig.configureHostDNSPolicies(strHost);
                if (strHost.equals(strMonitorHost)) {
@@ -1425,6 +1482,39 @@ public class IoTMaster {
                }
        }
 
+       /**
+        * A method to create a thread for policy deployment
+        *
+        * @param  setHostAddresses             Set of strings for host addresses to configure
+        * @return                              void
+        */
+       private void createMACPolicyThreads(Set<String> setHostAddresses) throws IOException {
+
+               // Create a list of threads
+               List<Thread> threads = new ArrayList<Thread>();
+               // Start threads for hosts
+               for(String strAddress : setHostAddresses) {
+                       Thread policyThread = new Thread(new Runnable() {
+                               public void run() {
+                                       synchronized(this) {
+                                               processJailConfig.sendMACPolicies(strAddress);
+                                       }
+                               }
+                       });
+                       threads.add(policyThread);
+                       policyThread.start();
+                       RuntimeOutput.print("Deploying MAC policies for: " + strAddress, BOOL_VERBOSE);
+               }
+               // Join all threads
+               for (Thread thread : threads) {
+                       try {
+                               thread.join();
+                       } catch (InterruptedException ex) {
+                               ex.printStackTrace();
+                       }
+               }
+       }
+
 
        /**
         * A method to send files to Java IoTSlave
@@ -1552,17 +1642,6 @@ public class IoTMaster {
         *
         * @return       String
         */
-       /*private String getCmdJavaIoTSlave(String strObjControllerName) {
-
-               return STR_SSH + " " + STR_USERNAME + strIoTSlaveControllerHostAdd + " cd " +
-                                       STR_RUNTIME_DIR + " sudo java " + STR_JVM_INIT_HEAP_SIZE + " " + 
-                                       STR_JVM_MAX_HEAP_SIZE + " " + STR_CLS_PATH + " " +
-                                       STR_RMI_PATH + " " + STR_IOT_SLAVE_CLS + " " + strIoTMasterHostAdd + " " +
-                                       commHan.getComPort(strObjControllerName) + " " +
-                                       commHan.getRMIRegPort(strObjControllerName) + " " +
-                                       commHan.getRMIStubPort(strObjControllerName) + " >& " +
-                                       STR_LOG_FILE_PATH + strObjControllerName + ".log &";
-       }*/
        private String getCmdJavaIoTSlave(String strObjControllerName) {
 
                // Create an Shell executable
@@ -1938,13 +2017,15 @@ public class IoTMaster {
                try {
                        // Extract hostname for this IoTMaster from MySQL DB
                        strIoTMasterHostAdd = routerConfig.getIPFromMACAddress(STR_MASTER_MAC_ADD);
+                   // Assign a new list of PrintWriter objects
+           routerConfig.renewPrintWriter();
+           HashSet<String> setAddresses = null;
                        // Loop as we can still find controller/device classes
                        for(int i=0; i<strObjectNames.length; i++) {
                                // PROFILING
                                start = System.currentTimeMillis();
-
-                               // Assign a new list of PrintWriter objects
-                               routerConfig.renewPrintWriter();
+                       // Assign a new list of main PrintWriter objects
+               routerConfig.renewMainPrintWriter();
                                // Get controller names one by one
                                String strObjControllerName = strObjectNames[i];
                                // Use LoadBalancer to assign a host address
@@ -2018,7 +2099,19 @@ public class IoTMaster {
                                        sendFileToCppSlave(strControllerFilePath, strControllerZipFile);
                                        createMainObjectCpp(strObjControllerName, outStream, inStream);
                                }
-
+                               // Write basic MAC policies for controller
+                               //String strFileName = STR_MAC_POL_PATH + strObjControllerName + STR_MAC_POLICY_EXT;
+                               if (STR_ACTIVATE_SANDBOXING.equals("Yes")) {
+                                       String strFileName = STR_MAC_POL_PATH + STR_JAVA + STR_MAC_POLICY_EXT;
+                                       processJailConfig.configureProcessJailControllerPolicies(strObjControllerName, strFileName, 
+                                               strIoTMasterHostAdd, commHan.getComPort(strObjControllerName));
+                               // Whether or not we need additional Tomoyo policy?
+                                   String strAddMACPolicy = parseConfigFile(strControllerCfg, STR_ADD_MAC_POL);
+                                   if (strAddMACPolicy != null && strAddMACPolicy.equals("Yes")) {
+                                   String strContMACCfg = STR_CONT_PATH + strObjControllerName + "/";
+                                       processJailConfig.combineAdditionalMACPolicy(strContMACCfg, strObjControllerName, strObjControllerName);
+                                   }
+                               }
                                // PROFILING
                                result = System.currentTimeMillis()-start;
                                System.out.println("\n\n ==> From IoTSlave start until main controller object is created: " + result);
@@ -2053,6 +2146,11 @@ public class IoTMaster {
                                        // SetInstrumenter vs. RelationInstrumenter
                                        String strFieldName = map.getKey();
                                        String strClassName = map.getValue().getClass().getName();
+
+                           System.out.println("\n\nDEBUG: Instrumenting IoTSet and IoTRelation objects!!!");
+                           System.out.println("DEBUG: Field name: " + strFieldName);
+                           System.out.println("DEBUG: Class name: " + strFieldName + "\n\n");
+
                                        if(strClassName.equals(STR_SET_INSTRUMENTER_CLS)) {
                                                SetInstrumenter setInstrumenter = (SetInstrumenter) map.getValue();
                                                if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) { 
@@ -2065,16 +2163,21 @@ public class IoTMaster {
                                                        throw new Error(strErrMsg);
                                                } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ADD_CLS)) { 
                                                // Instrument the IoTAddress
-                                                       setRouterPolicyIoTSetAddress(strFieldName, map, strIoTSlaveControllerHostAdd);
+                                                       setRouterPolicyIoTSetAddress(strFieldName, map, strIoTSlaveControllerHostAdd, strObjControllerName);
                                                        instrumentIoTSetAddress(strFieldName, strFieldName, inStream, outStream, STR_LANGUAGE_CONTROLLER);
                                                } else {
                                                // Any other cases
-                                                       instrumentIoTSet(map, strFieldName, STR_LANGUAGE_CONTROLLER);
+                                                       instrumentIoTSet(map, strFieldName, strObjControllerName, STR_LANGUAGE_CONTROLLER);
                                                }
                                        } else if (strClassName.equals(STR_REL_INSTRUMENTER_CLS)) {
-                                               instrumentIoTRelation(map, strFieldName, STR_LANGUAGE_CONTROLLER);
+                                               instrumentIoTRelation(map, strFieldName, strObjControllerName, STR_LANGUAGE_CONTROLLER);
                                        }
                                }
+                               // Combine controller MAC policies with the main policy file for the host
+                               String strTempFileName = "./" + strObjControllerName + STR_MAC_POLICY_EXT;
+                               processJailConfig.combineControllerMACPolicies(strIoTSlaveControllerHostAdd, strObjControllerName, strTempFileName);
+                               processJailConfig.flush();
+
                                // PROFILING
                                result = System.currentTimeMillis()-start;
                                System.out.println("\n\n ==> Time needed to instrument device driver objects: " + result + "\n\n");
@@ -2083,22 +2186,20 @@ public class IoTMaster {
                                // PROFILING
                                start = System.currentTimeMillis();
 
-                               // ROUTING POLICY: Deploy basic policies if this is the last controller
-                               if (i == strObjectNames.length-1) {
-                                       // ROUTING POLICY: implement basic policies to reject all other irrelevant traffics
-                                       for(String s: commHan.getHosts()) {
-                                               setHostBasicPolicies(s);
-                                       }
-                                       // We retain all the basic policies for router, 
-                                       // but we delete the initial allowance policies for internal all TCP and UDP communications
-                                       setRouterBasicPolicies(STR_ROUTER_ADD);
+                               // ROUTING POLICY: implement basic policies to reject all other irrelevant traffics
+                               for(String s: commHan.getHosts()) {
+                                       setHostBasicPolicies(s);
                                }
-                               // Close access to policy files and deploy policies
-                               routerConfig.close();
+                               // We retain all the basic policies for router, 
+                               // but we delete the initial allowance policies for internal all TCP and UDP communications
+                               setRouterBasicPolicies(STR_ROUTER_ADD);
+                               routerConfig.closeMain();
                                // Deploy the policy
-                               HashSet<String> setAddresses = new HashSet<String>(commHan.getHosts());
+                               setAddresses = new HashSet<String>(commHan.getHosts());
                                setAddresses.add(strIoTMasterHostAdd);
-                               createPolicyThreads(STR_ROUTER_ADD, setAddresses);
+                               // See if firewall policy is configured to be "on" or "off"
+                               if (STR_POLICY_ON.equals(STR_YES))
+                                       createPolicyThreads(STR_ROUTER_ADD, setAddresses);
 
                                // PROFILING
                                result = System.currentTimeMillis()-start;
@@ -2141,9 +2242,16 @@ public class IoTMaster {
                                inStream.close();
                                socket.close();
                                serverSocket.close();
+                               objInitHand.clearObjectInitHandler();
                                commHan.printLists();
+                               commHan.clearCommunicationHandler();
                                lbIoT.printHostInfo();
                        }
+                       // Close access to policy files and deploy policies
+                       routerConfig.close();
+                       processJailConfig.close();
+                       if (STR_ACTIVATE_SANDBOXING.equals("Yes"))
+                               createMACPolicyThreads(setAddresses);
 
                } catch (IOException          |
                                 InterruptedException |