/* * Copyright 2009-2014 Jagornet Technologies, LLC. All Rights Reserved. * * This software is the proprietary information of Jagornet Technologies, LLC. * Use is subject to license terms. * */ /* * This file DhcpServerPolicies.java is part of Jagornet DHCP. * * Jagornet DHCP is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Jagornet DHCP is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Jagornet DHCP. If not, see <http://www.gnu.org/licenses/>. * */ package com.jagornet.dhcp.server.config; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.util.List; import java.util.Properties; import com.jagornet.dhcp.message.DhcpMessage; import com.jagornet.dhcp.xml.Filter; import com.jagornet.dhcp.xml.FiltersType; import com.jagornet.dhcp.xml.Link; import com.jagornet.dhcp.xml.LinkFilter; import com.jagornet.dhcp.xml.LinkFiltersType; import com.jagornet.dhcp.xml.PoliciesType; import com.jagornet.dhcp.xml.Policy; /** * The Class DhcpServerPolicies. * Description: The class representing the DHCPv6 server policies. Policy defaults * are defined herein by the Property enum. These defaults can be overridden by loading * a standard Java properties file. At runtime, the value of any given property is taken * from the server's XML configuration file via the <policy> element with the corresponding * name. Some policies are supported only globally, e.g. queueSize, whereas others may be * defined at various "levels" of the DHCP server's XML configuration, e.g. preferredLifetime, * which will allow for lower-level overrides of global or other hierarchical policy values. * * @author A. Gregory Rabil */ public class DhcpServerPolicies { /** * The Property enum. */ public enum Property { CHANNEL_THREADPOOL_SIZE("channel.threadPoolSize", "16"), CHANNEL_MAX_CHANNEL_MEMORY("channel.maxChannelMemory", "1048576"), // 1024 x 1024 CHANNEL_MAX_TOTAL_MEMORY("channel.maxTotalMemory", "1048576"), // 1024 x 1024 CHANNEL_READ_BUFFER_SIZE("channel.readBufferSize", "307200"), // 300 bytes x 1K clients CHANNEL_WRITE_BUFFER_SIZE("channel.writeBufferSize", "307200"), // 300 bytes x 1K clients DATABASE_SCHEMA_TYTPE("database.schemaType", "jdbc-derby"), DATABASE_SCHEMA_VERSION("database.schemaVersion", "2"), DHCP_PROCESSOR_RECENT_MESSAGE_TIMER("dhcp.processor.recentMessageTimer", "5000"), DHCP_IGNORE_LOOPBACK("dhcp.ignoreLoopback", "true"), DHCP_IGNORE_LINKLOCAL("dhcp.ignoreLinkLocal", "true"), DHCP_IGNORE_SELF_PACKETS("dhcp.ignoreSelfPackets", "true"), BINDING_MANAGER_REAPER_STARTUP_DELAY("binding.manager.reaper.startupDelay", "10000"), BINDING_MANAGER_REAPER_RUN_PERIOD("binding.manager.reaper.runPeriod", "60000"), BINDING_MANAGER_OFFER_EXPIRATION("binding.manager.offerExpiration", "12000"), BINDING_MANAGER_DELETE_OLD_BINDINGS("binding.manager.deleteOldBindings", "false"), SEND_REQUESTED_OPTIONS_ONLY("sendRequestedOptionsOnly", "false"), SUPPORT_RAPID_COMMIT("supportRapidCommit", "false"), VERIFY_UNKNOWN_REBIND("verifyUnknownRebind", "false"), PREFERRED_LIFETIME("preferredLifetime", "3600"), VALID_LIFETIME("validLifetime", "3600"), IA_NA_T1("iaNaT1", "0.5"), IA_NA_T2("iaNaT2", "0.8"), IA_PD_T1("iaPdT1", "0.5"), IA_PD_T2("iaPdT2", "0.8"), DDNS_UPDATE("ddns.update", "none"), // acceptable values: none, server, client, etc... DDNS_SYNCHRONIZE("ddns.synchronize", "false"), DDNS_DOMAIN("ddns.domain", ""), DDNS_TTL("ddns.ttl", "0.3"), // 1/3 of the lifetime DDNS_SERVER("ddns.server", ""), DDNS_TSIG_KEYNAME("ddns.tsig.keyName", ""), DDNS_TSIG_ALGORITHM("ddns.tsig.algorithm", ""), DDNS_TSIG_KEYDATA("ddns.tsig.keyData", ""), DDNS_FORWARD_ZONE_NAME("ddns.forward.zone.name", ""), DDNS_FORWARD_ZONE_TTL("ddns.forward.zone.ttl", "0.3"), DDNS_FORWARD_ZONE_SERVER("ddns.forward.zone.server", ""), DDNS_FORWARD_ZONE_TSIG_KEYNAME("ddns.forward.zone.tsig.keyName", ""), DDNS_FORWARD_ZONE_TSIG_ALGORITHM("ddns.forward.zone.tsig.algorithm", ""), DDNS_FORWARD_ZONE_TSIG_KEYDATA("ddns.forward.zone.tsig.keyData", ""), DDNS_REVERSE_ZONE_NAME("ddns.reverse.zone.name", ""), DDNS_REVERSE_ZONE_BITLENGTH("ddns.reverse.zone.bitLength", "64"), DDNS_REVERSE_ZONE_TTL("ddns.reverse.zone.ttl", "0.3"), DDNS_REVERSE_ZONE_SERVER("ddns.reverse.zone.server", ""), DDNS_REVERSE_ZONE_TSIG_KEYNAME("ddns.reverse.zone.tsig.keyName", ""), DDNS_REVERSE_ZONE_TSIG_ALGORITHM("ddns.reverse.zone.tsig.algorithm", ""), DDNS_REVERSE_ZONE_TSIG_KEYDATA("ddns.reverse.zone.tsig.keyData", ""), V4_HEADER_SNAME("v4.header.sname", ""), V4_HEADER_FILENAME("v4.header.filename", ""), V4_IGNORED_MACS("v4.ignoredMacAddrs", "000000000000, FFFFFFFFFFFF"), V4_DEFAULT_LEASETIME("v4.defaultLeasetime", "3600"), V4_PINGCHECK_TIMEOUT("v4.pingCheckTimeout", "0"), ; /** The key. */ private final String key; /** The value. */ private final String value; /** * Instantiates a new property. * * @param key the key * @param value the value */ Property(String key, String value) { this.key = key; this.value = value; } /** * Key. * * @return the string */ public String key() { return key; } /** * Value. * * @return the string */ public String value() { return value; } } /** The Constant DEFAULT_PROPERTIES. */ protected static final Properties DEFAULT_PROPERTIES = new Properties(); static { Property[] defaultProperties = Property.values(); for (Property prop : defaultProperties) { DEFAULT_PROPERTIES.put(prop.key(), prop.value()); } } /** The SERVER properties. */ protected static Properties SERVER_PROPERTIES = new Properties(DEFAULT_PROPERTIES); /** * Load properties file. * * @param propertiesFilename the properties filename * * @throws IOException the exception */ public static void loadPropertiesFile(String propertiesFilename) throws IOException { Reader reader = null; try { reader = new FileReader(propertiesFilename); SERVER_PROPERTIES.load(reader); } finally { if (reader != null) { reader.close(); } } } /** * For testing, allow direct manipulation of policy values. * * @param name the name * @param value the value */ public static void setProperty(Property prop, String value) { if (SERVER_PROPERTIES != null) { SERVER_PROPERTIES.setProperty(prop.key(), value); } } /** * Gets the properties. * * @return the properties */ public static Properties getProperties() { return SERVER_PROPERTIES; } /** * Global policy. * * @param prop the prop * * @return the string */ public static String globalPolicy(Property prop) { String policy = getPolicy(DhcpServerConfiguration.getInstance().getDhcpServerConfig().getPolicies(), prop.key()); if (policy != null) { return policy; } return SERVER_PROPERTIES.getProperty(prop.key()); } /** * Global policy as boolean. * * @param prop the prop * * @return true, if successful */ public static boolean globalPolicyAsBoolean(Property prop) { return Boolean.parseBoolean(globalPolicy(prop)); } /** * Global policy as int. * * @param prop the prop * * @return the int */ public static int globalPolicyAsInt(Property prop) { return Integer.parseInt(globalPolicy(prop)); } /** * Global policy as long. * * @param prop the prop * * @return the long */ public static long globalPolicyAsLong(Property prop) { return Long.parseLong(globalPolicy(prop)); } /** * Global policy as float. * * @param prop the prop * * @return the float */ public static float globalPolicyAsFloat(Property prop) { return Float.parseFloat(globalPolicy(prop)); } /** * Global policy as string. * * @param requestMsg the request msg * @param prop the prop * @return the string */ public static String globalPolicy(DhcpMessage requestMsg, Property prop) { DhcpServerConfiguration config = DhcpServerConfiguration.getInstance(); String policy = null; if (requestMsg != null) { FiltersType filtersType = config.getDhcpServerConfig().getFilters(); if (filtersType != null) { List<Filter> filters = filtersType.getFilterList(); for (Filter filter : filters) { if (DhcpServerConfiguration.msgMatchesFilter(requestMsg, filter)) { policy = getPolicy(filter.getPolicies(), prop.key()); } } // if the client request matches at least one global filter, // and that filter has configured a value for the policy, then // return that value from the last filter that the client matches if (policy != null) { return policy; } } } // client does not match a global filter // get the value of the global policy, if any policy = getPolicy(config.getDhcpServerConfig().getPolicies(), prop.key()); if (policy != null) { return policy; } // fall back to the configured default value return SERVER_PROPERTIES.getProperty(prop.key()); } /** * Global policy as boolean. * * @param requestMsg the request msg * @param prop the prop * @return true, if successful */ public static boolean globalPolicyAsBoolean(DhcpMessage requestMsg, Property prop) { return Boolean.parseBoolean(globalPolicy(requestMsg, prop)); } /** * Global policy as int. * * @param requestMsg the request msg * @param prop the prop * @return the int */ public static int globalPolicyAsInt(DhcpMessage requestMsg, Property prop) { return Integer.parseInt(globalPolicy(requestMsg, prop)); } /** * Global policy as long. * * @param requestMsg the request msg * @param prop the prop * @return the long */ public static long globalPolicyAsLong(DhcpMessage requestMsg, Property prop) { return Long.parseLong(globalPolicy(requestMsg, prop)); } /** * Global policy as float. * * @param requestMsg the request msg * @param prop the prop * @return the float */ public static float globalPolicyAsFloat(DhcpMessage requestMsg, Property prop) { return Float.parseFloat(globalPolicy(requestMsg, prop)); } /** * Effective policy. * * @param link the link * @param prop the prop * * @return the string */ public static String effectivePolicy(Link link, Property prop) { String policy = getPolicy(link.getPolicies(), prop.key()); if (policy != null) { return policy; } return globalPolicy(prop); } /** * Effective policy as boolean. * * @param link the link * @param prop the prop * * @return true, if successful */ public static boolean effectivePolicyAsBoolean(Link link, Property prop) { return Boolean.parseBoolean(effectivePolicy(link, prop)); } /** * Effective policy as int. * * @param link the link * @param prop the prop * * @return the int */ public static int effectivePolicyAsInt(Link link, Property prop) { return Integer.parseInt(effectivePolicy(link, prop)); } /** * Effective policy as long. * * @param link the link * @param prop the prop * * @return the long */ public static long effectivePolicyAsLong(Link link, Property prop) { return Long.parseLong(effectivePolicy(link, prop)); } /** * Effective policy as float. * * @param link the link * @param prop the prop * * @return the float */ public static float effectivePolicyAsFloat(Link link, Property prop) { return Float.parseFloat(effectivePolicy(link, prop)); } /** * Effective policy. * * @param requestMsg the request msg * @param link the link * @param prop the prop * @return the string */ public static String effectivePolicy(DhcpMessage requestMsg, Link link, Property prop) { String policy = null; if ((requestMsg != null) && (link != null)) { LinkFiltersType linkFiltersType = link.getLinkFilters(); if (linkFiltersType != null) { List<LinkFilter> linkFilters = linkFiltersType.getLinkFilterList(); if (linkFilters != null) { for (LinkFilter linkFilter : linkFilters) { if (DhcpServerConfiguration.msgMatchesFilter(requestMsg, linkFilter)) { policy = getPolicy(linkFilter.getPolicies(), prop.key()); } } // if the client request matches at least one filter on the link, // and that filter has configured a value for the policy, then return // that value from the last filter that the client matches if (policy != null) { return policy; } } } } if (link != null) { // client does not match a link filter // get the value of the policy on the link, if any policy = getPolicy(link.getPolicies(), prop.key()); if (policy != null) { return policy; } } return globalPolicy(prop); } /** * Effective policy as boolean. * * @param requestMsg the request msg * @param link the link * @param prop the prop * @return true, if successful */ public static boolean effectivePolicyAsBoolean(DhcpMessage requestMsg, Link link, Property prop) { return Boolean.parseBoolean(effectivePolicy(requestMsg, link, prop)); } /** * Effective policy as int. * * @param requestMsg the request msg * @param link the link * @param prop the prop * @return the int */ public static int effectivePolicyAsInt(DhcpMessage requestMsg, Link link, Property prop) { return Integer.parseInt(effectivePolicy(requestMsg, link, prop)); } /** * Effective policy as long. * * @param requestMsg the request msg * @param link the link * @param prop the prop * @return the long */ public static long effectivePolicyAsLong(DhcpMessage requestMsg, Link link, Property prop) { return Long.parseLong(effectivePolicy(requestMsg, link, prop)); } /** * Effective policy as float. * * @param requestMsg the request msg * @param link the link * @param prop the prop * @return the float */ public static float effectivePolicyAsFloat(DhcpMessage requestMsg, Link link, Property prop) { return Float.parseFloat(effectivePolicy(requestMsg, link, prop)); } /** * Effective policy. * * @param pool the pool * @param link the link * @param prop the prop * * @return the string */ public static String effectivePolicy(DhcpConfigObject configObj, Link link, Property prop) { String policy = null; if (configObj != null) { policy = getPolicy(configObj.getPolicies(), prop.key()); if (policy != null) { return policy; } } if (link != null) { policy = getPolicy(link.getPolicies(), prop.key()); if (policy != null) { return policy; } } return globalPolicy(prop); } /** * Effective policy as boolean. * * @param pool the pool * @param link the link * @param prop the prop * * @return true, if successful */ public static boolean effectivePolicyAsBoolean(DhcpConfigObject configObj, Link link, Property prop) { return Boolean.parseBoolean(effectivePolicy(configObj, link, prop)); } /** * Effective policy as int. * * @param pool the pool * @param link the link * @param prop the prop * * @return the int */ public static int effectivePolicyAsInt(DhcpConfigObject configObj, Link link, Property prop) { return Integer.parseInt(effectivePolicy(configObj, link, prop)); } /** * Effective policy as long. * * @param pool the pool * @param link the link * @param prop the prop * * @return the long */ public static long effectivePolicyAsLong(DhcpConfigObject configObj, Link link, Property prop) { return Long.parseLong(effectivePolicy(configObj, link, prop)); } /** * Effective policy as float. * * @param pool the pool * @param link the link * @param prop the prop * * @return the float */ public static float effectivePolicyAsFloat(DhcpConfigObject configObj, Link link, Property prop) { return Float.parseFloat(effectivePolicy(configObj, link, prop)); } /** * Effective policy. * * @param requestMsg the request msg * @param filtersType the filters type * @param policiesType the policies type * @param link the link * @param prop the prop * @return the string */ public static String effectivePolicy(DhcpMessage requestMsg, DhcpConfigObject configObj, Link link, Property prop) { String policy = null; if ((requestMsg != null) && (configObj != null)) { if (configObj.getFilters() != null) { List<Filter> filters = configObj.getFilters().getFilterList(); if (filters != null) { for (Filter filter : filters) { if (DhcpServerConfiguration.msgMatchesFilter(requestMsg, filter)) { policy = getPolicy(filter.getPolicies(), prop.key()); } } // if the client request matches at least one filter on the pool, // and that filter has configured a value for the policy, then return // that value from the last filter that the client matches if (policy != null) { return policy; } } } } if (configObj != null) { // client does not match a pool filter // get the value of the policy on the pool, if any policy = getPolicy(configObj.getPolicies(), prop.key()); if (policy != null) { return policy; } } return effectivePolicy(requestMsg, link, prop); } /** * Effective policy as boolean. * * @param requestMsg the request msg * @param pool the pool * @param link the link * @param prop the prop * @return true, if successful */ public static boolean effectivePolicyAsBoolean(DhcpMessage requestMsg, DhcpConfigObject configObj, Link link, Property prop) { return Boolean.parseBoolean(effectivePolicy(requestMsg, configObj, link, prop)); } /** * Effective policy as int. * * @param requestMsg the request msg * @param pool the pool * @param link the link * @param prop the prop * @return the int */ public static int effectivePolicyAsInt(DhcpMessage requestMsg, DhcpConfigObject configObj, Link link, Property prop) { return Integer.parseInt(effectivePolicy(requestMsg, configObj, link, prop)); } /** * Effective policy as long. * * @param requestMsg the request msg * @param pool the pool * @param link the link * @param prop the prop * @return the long */ public static long effectivePolicyAsLong(DhcpMessage requestMsg, DhcpConfigObject configObj, Link link, Property prop) { return Long.parseLong(effectivePolicy(requestMsg, configObj, link, prop)); } /** * Effective policy as float. * * @param requestMsg the request msg * @param pool the pool * @param link the link * @param prop the prop * @return the float */ public static float effectivePolicyAsFloat(DhcpMessage requestMsg, DhcpConfigObject configObj, Link link, Property prop) { return Float.parseFloat(effectivePolicy(requestMsg, configObj, link, prop)); } /** * Gets the policy. * * @param policies the policies * @param name the name * * @return the policy */ protected static String getPolicy(PoliciesType policies, String name) { if (policies != null) { List<Policy> policyList = policies.getPolicyList(); if (policyList != null) { for (Policy policy : policyList) { if (policy.getName().equalsIgnoreCase(name)) { return policy.getValue(); } } } } return null; } }