mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Matthew Swift
25.05.2014 2117f562f38b63e27b695d05c81e46afdbe6b1a4
Avoid potential DNS lookups when validating IPv6 address masks.

* on my machine, which has IPv6 networking, the test for invalid IPv6 address masks was taking 60 seconds to complete, or 10s per attempted decode
* use reflection to invoke sun.net.util.IPAddressUtil#isIPv6LiteralAddress() if it is available.
1 files modified
34 ■■■■■ changed files
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AddressMask.java 34 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AddressMask.java
@@ -28,6 +28,7 @@
import static com.forgerock.opendj.ldap.CoreMessages.*;
import java.lang.reflect.Method;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
@@ -195,7 +196,6 @@
     *             If the rule type cannot be determined from the rule string.
     */
    private void determineRuleType(final String ruleString) {
        // Rule ending with '.' is invalid'
        if (ruleString.endsWith(".")) {
            throw genericDecodeError();
@@ -428,9 +428,37 @@
     */
    private void processIPv6(final String rule) {
        final String[] s = rule.split("/", -1);
        InetAddress addr;
        final String address = s[0];
        // Try to avoid calling InetAddress.getByName() because it may do a reverse lookup.
        final String ipv6Literal;
        if (address.charAt(0) == '[' && address.charAt(address.length() - 1) == ']') {
            // isIPv4LiteralAddress must be invoked without surrounding brackets.
            ipv6Literal = address.substring(1, address.length() - 1);
        } else {
            ipv6Literal = address;
        }
        Boolean isValid;
        try {
            addr = InetAddress.getByName(s[0]);
            // Use reflection to avoid dependency on Sun JRE.
            final Class<?> ipUtils = Class.forName("sun.net.util.IPAddressUtil");
            final Method method = ipUtils.getMethod("isIPv6LiteralAddress", String.class);
            isValid = (Boolean) method.invoke(null, ipv6Literal);
        } catch (Exception e) {
            /*
             * Unable to invoke Sun private API. Assume it's ok, but accept that
             * a DNS query may be performed if it is not valid.
             */
            isValid = true;
        }
        if (!isValid) {
            throw genericDecodeError();
        }
        final InetAddress addr;
        try {
            addr = InetAddress.getByName(address);
        } catch (final UnknownHostException ex) {
            throw genericDecodeError();
        }