# HG changeset patch # User jwilhelm # Date 1548183379 -3600 # Node ID ccfd4e614bb8a648d2d4179facac7ab195166e8b # Parent 1ae8236173955edc7fe19d5e34a0c4f01c5b51ff# Parent 1b292ae4eb50061b4f2fb280ecf4453ba2a8071c Merge diff -r 1ae823617395 -r ccfd4e614bb8 src/hotspot/share/jvmci/jvmciEnv.cpp --- a/src/hotspot/share/jvmci/jvmciEnv.cpp Tue Jan 22 03:32:47 2019 -0800 +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp Tue Jan 22 19:56:19 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,9 +63,30 @@ { // Get Jvmti capabilities under lock to get consistent values. MutexLocker mu(JvmtiThreadState_lock); - _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint(); - _jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables(); - _jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions(); + _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint() ? 1 : 0; + _jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables() ? 1 : 0; + _jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions() ? 1 : 0; + _jvmti_can_pop_frame = JvmtiExport::can_pop_frame() ? 1 : 0; +} + +bool JVMCIEnv::jvmti_state_changed() const { + if (!jvmti_can_access_local_variables() && + JvmtiExport::can_access_local_variables()) { + return true; + } + if (!jvmti_can_hotswap_or_post_breakpoint() && + JvmtiExport::can_hotswap_or_post_breakpoint()) { + return true; + } + if (!jvmti_can_post_on_exceptions() && + JvmtiExport::can_post_on_exceptions()) { + return true; + } + if (!jvmti_can_pop_frame() && + JvmtiExport::can_pop_frame()) { + return true; + } + return false; } // ------------------------------------------------------------------ @@ -413,11 +434,9 @@ JVMCIEnv::CodeInstallResult JVMCIEnv::validate_compile_task_dependencies(Dependencies* dependencies, Handle compiled_code, JVMCIEnv* env, char** failure_detail) { // If JVMTI capabilities were enabled during compile, the compilation is invalidated. - if (env != NULL) { - if (!env->_jvmti_can_hotswap_or_post_breakpoint && JvmtiExport::can_hotswap_or_post_breakpoint()) { - *failure_detail = (char*) "Hotswapping or breakpointing was enabled during compilation"; - return JVMCIEnv::dependencies_failed; - } + if (env != NULL && env->jvmti_state_changed()) { + *failure_detail = (char*) "Jvmti state change during compilation invalidated dependencies"; + return JVMCIEnv::dependencies_failed; } // Dependencies must be checked when the system dictionary changes diff -r 1ae823617395 -r ccfd4e614bb8 src/hotspot/share/jvmci/jvmciEnv.hpp --- a/src/hotspot/share/jvmci/jvmciEnv.hpp Tue Jan 22 03:32:47 2019 -0800 +++ b/src/hotspot/share/jvmci/jvmciEnv.hpp Tue Jan 22 19:56:19 2019 +0100 @@ -105,10 +105,13 @@ // Specifies if _failure_reason is on the C heap. bool _failure_reason_on_C_heap; - // Cache JVMTI state - bool _jvmti_can_hotswap_or_post_breakpoint; - bool _jvmti_can_access_local_variables; - bool _jvmti_can_post_on_exceptions; + // Cache JVMTI state. Defined as bytes so that reading them from Java + // via Unsafe is well defined (the C++ type for bool is implementation + // defined and may not be the same as a Java boolean). + jbyte _jvmti_can_hotswap_or_post_breakpoint; + jbyte _jvmti_can_access_local_variables; + jbyte _jvmti_can_post_on_exceptions; + jbyte _jvmti_can_pop_frame; // Implementation methods for loading and constant pool access. static Klass* get_klass_by_name_impl(Klass* accessing_klass, @@ -147,6 +150,12 @@ public: CompileTask* task() { return _task; } + bool jvmti_state_changed() const; + bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint != 0; } + bool jvmti_can_access_local_variables() const { return _jvmti_can_access_local_variables != 0; } + bool jvmti_can_post_on_exceptions() const { return _jvmti_can_post_on_exceptions != 0; } + bool jvmti_can_pop_frame() const { return _jvmti_can_pop_frame != 0; } + const char* failure_reason() { return _failure_reason; } bool failure_reason_on_C_heap() { return _failure_reason_on_C_heap; } bool retryable() { return _retryable; } diff -r 1ae823617395 -r ccfd4e614bb8 src/hotspot/share/jvmci/vmStructs_jvmci.cpp --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp Tue Jan 22 03:32:47 2019 -0800 +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp Tue Jan 22 19:56:19 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -182,13 +182,17 @@ nonstatic_field(JavaThread, _pending_failed_speculation, long) \ nonstatic_field(JavaThread, _pending_transfer_to_interpreter, bool) \ nonstatic_field(JavaThread, _jvmci_counters, jlong*) \ + nonstatic_field(JavaThread, _should_post_on_exceptions_flag, int) \ nonstatic_field(JavaThread, _reserved_stack_activation, address) \ \ static_field(java_lang_Class, _klass_offset, int) \ static_field(java_lang_Class, _array_klass_offset, int) \ \ nonstatic_field(JVMCIEnv, _task, CompileTask*) \ - nonstatic_field(JVMCIEnv, _jvmti_can_hotswap_or_post_breakpoint, bool) \ + nonstatic_field(JVMCIEnv, _jvmti_can_hotswap_or_post_breakpoint, jbyte) \ + nonstatic_field(JVMCIEnv, _jvmti_can_access_local_variables, jbyte) \ + nonstatic_field(JVMCIEnv, _jvmti_can_post_on_exceptions, jbyte) \ + nonstatic_field(JVMCIEnv, _jvmti_can_pop_frame, jbyte) \ \ nonstatic_field(InvocationCounter, _counter, unsigned int) \ \ diff -r 1ae823617395 -r ccfd4e614bb8 src/hotspot/share/opto/compile.cpp --- a/src/hotspot/share/opto/compile.cpp Tue Jan 22 03:32:47 2019 -0800 +++ b/src/hotspot/share/opto/compile.cpp Tue Jan 22 19:56:19 2019 +0100 @@ -2188,13 +2188,16 @@ // They were inserted during parsing (see add_safepoint()) to make // infinite loops without calls or exceptions visible to root, i.e., // useful. -void Compile::remove_root_to_sfpts_edges() { +void Compile::remove_root_to_sfpts_edges(PhaseIterGVN& igvn) { Node *r = root(); if (r != NULL) { for (uint i = r->req(); i < r->len(); ++i) { Node *n = r->in(i); if (n != NULL && n->is_SafePoint()) { r->rm_prec(i); + if (n->outcnt() == 0) { + igvn.remove_dead_node(n); + } --i; } } @@ -2263,7 +2266,7 @@ // Now that all inlining is over, cut edge from root to loop // safepoints - remove_root_to_sfpts_edges(); + remove_root_to_sfpts_edges(igvn); // Remove the speculative part of types and clean up the graph from // the extra CastPP nodes whose only purpose is to carry them. Do diff -r 1ae823617395 -r ccfd4e614bb8 src/hotspot/share/opto/compile.hpp --- a/src/hotspot/share/opto/compile.hpp Tue Jan 22 03:32:47 2019 -0800 +++ b/src/hotspot/share/opto/compile.hpp Tue Jan 22 19:56:19 2019 +0100 @@ -1088,7 +1088,7 @@ void inline_string_calls(bool parse_time); void inline_boxing_calls(PhaseIterGVN& igvn); bool optimize_loops(PhaseIterGVN& igvn, LoopOptsMode mode); - void remove_root_to_sfpts_edges(); + void remove_root_to_sfpts_edges(PhaseIterGVN& igvn); // Matching, CFG layout, allocation, code generation PhaseCFG* cfg() { return _cfg; } diff -r 1ae823617395 -r ccfd4e614bb8 src/java.base/share/classes/sun/security/validator/CADistrustPolicy.java --- a/src/java.base/share/classes/sun/security/validator/CADistrustPolicy.java Tue Jan 22 03:32:47 2019 -0800 +++ b/src/java.base/share/classes/sun/security/validator/CADistrustPolicy.java Tue Jan 22 19:56:19 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,17 +39,19 @@ enum CADistrustPolicy { /** * Distrust TLS Server certificates anchored by a Symantec root CA and - * issued after April 16, 2019. If enabled, this policy is currently - * enforced by the PKIX and SunX509 TrustManager implementations of the - * SunJSSE provider implementation. + * issued after April 16, 2019 (with exceptions for a couple of subordinate + * CAs, see the jdk.security.caDistrustPolicies definition in the + * java.security file for more details). If enabled, this policy is + * currently enforced by the PKIX and SunX509 TrustManager implementations + * of the SunJSSE provider implementation. */ SYMANTEC_TLS { - void checkDistrust(String variant, X509Certificate anchor, - X509Certificate ee) throws ValidatorException { + void checkDistrust(String variant, X509Certificate[] chain) + throws ValidatorException { if (!variant.equals(Validator.VAR_TLS_SERVER)) { return; } - SymantecTLSPolicy.checkDistrust(anchor, ee); + SymantecTLSPolicy.checkDistrust(chain); } }; @@ -57,13 +59,13 @@ * Checks if the end-entity certificate is distrusted. * * @param variant the type of certificate being checked - * @param anchor the trust anchor certificate - * @param ee the end-entity certificate to check + * @param chain the end-entity's certificate chain. The end entity cert + * is at index 0, the trust anchor at index n-1. * @throws ValidatorException if the end-entity certificate is distrusted */ abstract void checkDistrust(String variant, - X509Certificate anchor, - X509Certificate ee) throws ValidatorException; + X509Certificate[] chain) + throws ValidatorException; // The policies set in the jdk.security.caDistrustPolicies property. static final EnumSet POLICIES = parseProperty(); diff -r 1ae823617395 -r ccfd4e614bb8 src/java.base/share/classes/sun/security/validator/EndEntityChecker.java --- a/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java Tue Jan 22 03:32:47 2019 -0800 +++ b/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java Tue Jan 22 19:56:19 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -132,27 +132,26 @@ return new EndEntityChecker(type, variant); } - void check(X509Certificate cert, Object parameter, - boolean checkUnresolvedCritExts, X509Certificate anchor) - throws CertificateException { + void check(X509Certificate[] chain, Object parameter, + boolean checkUnresolvedCritExts) throws CertificateException { if (variant.equals(Validator.VAR_GENERIC)) { return; // no checks } - Set exts = getCriticalExtensions(cert); + Set exts = getCriticalExtensions(chain[0]); if (variant.equals(Validator.VAR_TLS_SERVER)) { - checkTLSServer(cert, (String)parameter, exts); + checkTLSServer(chain[0], (String)parameter, exts); } else if (variant.equals(Validator.VAR_TLS_CLIENT)) { - checkTLSClient(cert, exts); + checkTLSClient(chain[0], exts); } else if (variant.equals(Validator.VAR_CODE_SIGNING)) { - checkCodeSigning(cert, exts); + checkCodeSigning(chain[0], exts); } else if (variant.equals(Validator.VAR_JCE_SIGNING)) { - checkCodeSigning(cert, exts); + checkCodeSigning(chain[0], exts); } else if (variant.equals(Validator.VAR_PLUGIN_CODE_SIGNING)) { - checkCodeSigning(cert, exts); + checkCodeSigning(chain[0], exts); } else if (variant.equals(Validator.VAR_TSA_SERVER)) { - checkTSAServer(cert, exts); + checkTSAServer(chain[0], exts); } else { throw new CertificateException("Unknown variant: " + variant); } @@ -165,7 +164,7 @@ // check if certificate should be distrusted according to policies // set in the jdk.security.caDistrustPolicies security property for (CADistrustPolicy policy : CADistrustPolicy.POLICIES) { - policy.checkDistrust(variant, anchor, cert); + policy.checkDistrust(variant, chain); } } diff -r 1ae823617395 -r ccfd4e614bb8 src/java.base/share/classes/sun/security/validator/SymantecTLSPolicy.java --- a/src/java.base/share/classes/sun/security/validator/SymantecTLSPolicy.java Tue Jan 22 03:32:47 2019 -0800 +++ b/src/java.base/share/classes/sun/security/validator/SymantecTLSPolicy.java Tue Jan 22 19:56:19 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import java.time.Month; import java.time.ZoneOffset; import java.util.Date; +import java.util.Map; import java.util.Set; import sun.security.x509.X509CertImpl; @@ -119,6 +120,24 @@ "2399561127A57125DE8CEFEA610DDF2FA078B5C8067F4E828290BFB860E84B3C" ); + private static final LocalDate DECEMBER_31_2019 = + LocalDate.of(2019, Month.DECEMBER, 31); + // SHA-256 certificate fingerprints of subCAs with later distrust dates + private static final Map EXEMPT_SUBCAS = Map.of( + // Subject DN: C=US, O=Apple Inc., OU=Certification Authority, + // CN=Apple IST CA 2 - G1 + // Issuer DN: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US + "AC2B922ECFD5E01711772FEA8ED372DE9D1E2245FCE3F57A9CDBEC77296A424B", + DECEMBER_31_2019, + // Subject DN: C=US, O=Apple Inc., OU=Certification Authority, + // CN=Apple IST CA 8 - G1 + // Issuer DN: CN=GeoTrust Primary Certification Authority - G2, + // OU=(c) 2007 GeoTrust Inc. - For authorized use only, + // O=GeoTrust Inc., C=US + "A4FE7C7F15155F3F0AEF7AAA83CF6E06DEB97CA3F909DF920AC1490882D488ED", + DECEMBER_31_2019 + ); + // Any TLS Server certificate that is anchored by one of the Symantec // roots above and is issued after this date will be distrusted. private static final LocalDate APRIL_16_2019 = @@ -128,28 +147,47 @@ * This method assumes the eeCert is a TLS Server Cert and chains back to * the anchor. * - * @param anchor the trust anchor certificate - * @param eeCert the certificate to check + * @param chain the end-entity's certificate chain. The end entity cert + * is at index 0, the trust anchor at index n-1. * @throws ValidatorException if the certificate is distrusted */ - static void checkDistrust(X509Certificate anchor, - X509Certificate eeCert) + static void checkDistrust(X509Certificate[] chain) throws ValidatorException { - String fp = (anchor instanceof X509CertImpl) - ? ((X509CertImpl)anchor).getFingerprint("SHA-256") - : X509CertImpl.getFingerprint("SHA-256", anchor); - if (FINGERPRINTS.contains(fp)) { - // reject if certificate is issued after April 16, 2019 - Date notBefore = eeCert.getNotBefore(); + X509Certificate anchor = chain[chain.length-1]; + if (FINGERPRINTS.contains(fingerprint(anchor))) { + Date notBefore = chain[0].getNotBefore(); LocalDate ldNotBefore = LocalDate.ofInstant(notBefore.toInstant(), ZoneOffset.UTC); - if (ldNotBefore.isAfter(APRIL_16_2019)) { - throw new ValidatorException - ("TLS Server certificate issued after " + APRIL_16_2019 + - " and anchored by a distrusted legacy Symantec root CA: " - + anchor.getSubjectX500Principal(), - ValidatorException.T_UNTRUSTED_CERT, anchor); + // check if chain goes through one of the subCAs + if (chain.length > 2) { + X509Certificate subCA = chain[chain.length-2]; + LocalDate distrustDate = EXEMPT_SUBCAS.get(fingerprint(subCA)); + if (distrustDate != null) { + // reject if certificate is issued after specified date + checkNotBefore(ldNotBefore, distrustDate, anchor); + return; // success + } } + // reject if certificate is issued after April 16, 2019 + checkNotBefore(ldNotBefore, APRIL_16_2019, anchor); + } + } + + private static String fingerprint(X509Certificate cert) { + return (cert instanceof X509CertImpl) + ? ((X509CertImpl)cert).getFingerprint("SHA-256") + : X509CertImpl.getFingerprint("SHA-256", cert); + } + + private static void checkNotBefore(LocalDate notBeforeDate, + LocalDate distrustDate, X509Certificate anchor) + throws ValidatorException { + if (notBeforeDate.isAfter(distrustDate)) { + throw new ValidatorException + ("TLS Server certificate issued after " + distrustDate + + " and anchored by a distrusted legacy Symantec root CA: " + + anchor.getSubjectX500Principal(), + ValidatorException.T_UNTRUSTED_CERT, anchor); } } diff -r 1ae823617395 -r ccfd4e614bb8 src/java.base/share/classes/sun/security/validator/Validator.java --- a/src/java.base/share/classes/sun/security/validator/Validator.java Tue Jan 22 03:32:47 2019 -0800 +++ b/src/java.base/share/classes/sun/security/validator/Validator.java Tue Jan 22 19:56:19 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -274,9 +274,8 @@ // redundant. boolean checkUnresolvedCritExts = (type == TYPE_PKIX) ? false : true; - endEntityChecker.check(chain[0], parameter, - checkUnresolvedCritExts, - chain[chain.length-1]); + endEntityChecker.check(chain, parameter, + checkUnresolvedCritExts); } return chain; diff -r 1ae823617395 -r ccfd4e614bb8 src/java.base/share/conf/security/java.security --- a/src/java.base/share/conf/security/java.security Tue Jan 22 03:32:47 2019 -0800 +++ b/src/java.base/share/conf/security/java.security Tue Jan 22 19:56:19 2019 +0100 @@ -1167,8 +1167,15 @@ # of which represents a policy for determining if a CA should be distrusted. # The supported values are: # -# SYMANTEC_TLS : Distrust TLS Server certificates anchored by -# a Symantec root CA and issued after April 16, 2019. +# SYMANTEC_TLS : Distrust TLS Server certificates anchored by a Symantec +# root CA and issued after April 16, 2019 unless issued by one of the +# following subordinate CAs which have a later distrust date: +# 1. Apple IST CA 2 - G1, SHA-256 fingerprint: +# AC2B922ECFD5E01711772FEA8ED372DE9D1E2245FCE3F57A9CDBEC77296A424B +# Distrust after December 31, 2019. +# 2. Apple IST CA 8 - G1, SHA-256 fingerprint: +# A4FE7C7F15155F3F0AEF7AAA83CF6E06DEB97CA3F909DF920AC1490882D488ED +# Distrust after December 31, 2019. # # Leading and trailing whitespace surrounding each value are ignored. # Unknown values are ignored. If the property is commented out or set to the diff -r 1ae823617395 -r ccfd4e614bb8 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Tue Jan 22 03:32:47 2019 -0800 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Tue Jan 22 19:56:19 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -309,8 +309,11 @@ public final int jvmAccWrittenFlags = getConstant("JVM_ACC_WRITTEN_FLAGS", Integer.class); public final int jvmAccSynthetic = getConstant("JVM_ACC_SYNTHETIC", Integer.class); + public final int jvmciCompileStateCanPostOnExceptionsOffset = getFieldOffset("JVMCIEnv::_jvmti_can_post_on_exceptions", Integer.class, "jbyte", Integer.MIN_VALUE); + public final int threadTlabOffset = getFieldOffset("Thread::_tlab", Integer.class, "ThreadLocalAllocBuffer"); public final int javaThreadAnchorOffset = getFieldOffset("JavaThread::_anchor", Integer.class, "JavaFrameAnchor"); + public final int javaThreadShouldPostOnExceptionsFlagOffset = getFieldOffset("JavaThread::_should_post_on_exceptions_flag", Integer.class, "int", Integer.MIN_VALUE); public final int threadObjectOffset = getFieldOffset("JavaThread::_threadObj", Integer.class, "oop"); public final int osThreadOffset = getFieldOffset("JavaThread::_osthread", Integer.class, "OSThread*"); public final int threadIsMethodHandleReturnOffset = getFieldOffset("JavaThread::_is_method_handle_return", Integer.class, "int"); diff -r 1ae823617395 -r ccfd4e614bb8 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Tue Jan 22 03:32:47 2019 -0800 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Tue Jan 22 19:56:19 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -124,7 +124,7 @@ Plugins plugins = new Plugins(invocationPlugins); NodeIntrinsificationProvider nodeIntrinsificationProvider = new NodeIntrinsificationProvider(metaAccess, snippetReflection, foreignCalls, wordTypes); HotSpotWordOperationPlugin wordOperationPlugin = new HotSpotWordOperationPlugin(snippetReflection, wordTypes); - HotSpotNodePlugin nodePlugin = new HotSpotNodePlugin(wordOperationPlugin); + HotSpotNodePlugin nodePlugin = new HotSpotNodePlugin(wordOperationPlugin, config, wordTypes); plugins.appendTypePlugin(nodePlugin); plugins.appendNodePlugin(nodePlugin); diff -r 1ae823617395 -r ccfd4e614bb8 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotNodePlugin.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotNodePlugin.java Tue Jan 22 03:32:47 2019 -0800 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotNodePlugin.java Tue Jan 22 19:56:19 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,21 +24,41 @@ package org.graalvm.compiler.hotspot.meta; +import static jdk.vm.ci.meta.DeoptimizationAction.None; +import static jdk.vm.ci.meta.DeoptimizationReason.TransferToInterpreter; import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode; +import org.graalvm.compiler.core.common.CompilationIdentifier; +import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.core.common.type.StampPair; +import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; +import org.graalvm.compiler.hotspot.HotSpotCompilationIdentifier; +import org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode; +import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; import org.graalvm.compiler.nodes.ConstantNode; +import org.graalvm.compiler.nodes.FixedGuardNode; +import org.graalvm.compiler.nodes.FixedWithNextNode; +import org.graalvm.compiler.nodes.LogicNode; +import org.graalvm.compiler.nodes.NamedLocationIdentity; +import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.calc.IntegerEqualsNode; import org.graalvm.compiler.nodes.extended.GuardingNode; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderTool; import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin; import org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin; import org.graalvm.compiler.nodes.graphbuilderconf.TypePlugin; +import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType; +import org.graalvm.compiler.nodes.memory.ReadNode; +import org.graalvm.compiler.nodes.memory.address.AddressNode; +import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode; import org.graalvm.compiler.nodes.util.ConstantFoldUtil; import org.graalvm.compiler.word.Word; import org.graalvm.compiler.word.WordOperationPlugin; +import jdk.internal.vm.compiler.word.LocationIdentity; +import jdk.vm.ci.hotspot.HotSpotCompilationRequest; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaType; @@ -47,23 +67,30 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; +import java.lang.reflect.Field; +import sun.misc.Unsafe; + /** - * This plugin handles the HotSpot-specific customizations of bytecode parsing: - *

- * {@link Word}-type rewriting for {@link GraphBuilderContext#parsingIntrinsic intrinsic} functions - * (snippets and method substitutions), by forwarding to the {@link WordOperationPlugin}. Note that - * we forward the {@link NodePlugin} and {@link TypePlugin} methods, but not the + * This plugin does HotSpot-specific customization of bytecode parsing: + *

    + *
  • {@link Word}-type rewriting for {@link GraphBuilderContext#parsingIntrinsic intrinsic} + * functions (snippets and method substitutions), by forwarding to the {@link WordOperationPlugin}. + * Note that we forward the {@link NodePlugin} and {@link TypePlugin} methods, but not the * {@link InlineInvokePlugin} methods implemented by {@link WordOperationPlugin}. The latter is not * necessary because HotSpot only uses the {@link Word} type in methods that are force-inlined, - * i.e., there are never non-inlined invokes that involve the {@link Word} type. - *

    - * Constant folding of field loads. + * i.e., there are never non-inlined invokes that involve the {@link Word} type.

  • + *
  • Constant folding of field loads.
  • + *
*/ public final class HotSpotNodePlugin implements NodePlugin, TypePlugin { protected final WordOperationPlugin wordOperationPlugin; + private final GraalHotSpotVMConfig config; + private final HotSpotWordTypes wordTypes; - public HotSpotNodePlugin(WordOperationPlugin wordOperationPlugin) { + public HotSpotNodePlugin(WordOperationPlugin wordOperationPlugin, GraalHotSpotVMConfig config, HotSpotWordTypes wordTypes) { this.wordOperationPlugin = wordOperationPlugin; + this.config = config; + this.wordTypes = wordTypes; } @Override @@ -180,4 +207,58 @@ } return false; } + + @Override + public FixedWithNextNode instrumentExceptionDispatch(StructuredGraph graph, FixedWithNextNode afterExceptionLoaded) { + CompilationIdentifier id = graph.compilationId(); + if (id instanceof HotSpotCompilationIdentifier) { + HotSpotCompilationRequest request = ((HotSpotCompilationIdentifier) id).getRequest(); + if (request != null) { + long compileState = request.getJvmciEnv(); + if (compileState != 0 && + config.jvmciCompileStateCanPostOnExceptionsOffset != Integer.MIN_VALUE && + config.javaThreadShouldPostOnExceptionsFlagOffset != Integer.MIN_VALUE) { + long canPostOnExceptionsOffset = compileState + config.jvmciCompileStateCanPostOnExceptionsOffset; + boolean canPostOnExceptions = UNSAFE.getByte(canPostOnExceptionsOffset) != 0; + if (canPostOnExceptions) { + // If the exception capability is set, then generate code + // to check the JavaThread.should_post_on_exceptions flag to see + // if we actually need to report exception events for the current + // thread. If not, take the fast path otherwise deoptimize. + CurrentJavaThreadNode thread = graph.unique(new CurrentJavaThreadNode(wordTypes.getWordKind())); + ValueNode offset = graph.unique(ConstantNode.forLong(config.javaThreadShouldPostOnExceptionsFlagOffset)); + AddressNode address = graph.unique(new OffsetAddressNode(thread, offset)); + ReadNode shouldPostException = graph.add(new ReadNode(address, JAVA_THREAD_SHOULD_POST_ON_EXCEPTIONS_FLAG_LOCATION, StampFactory.intValue(), BarrierType.NONE)); + afterExceptionLoaded.setNext(shouldPostException); + ValueNode zero = graph.unique(ConstantNode.forInt(0)); + LogicNode cond = graph.unique(new IntegerEqualsNode(shouldPostException, zero)); + FixedGuardNode check = graph.add(new FixedGuardNode(cond, TransferToInterpreter, None, false)); + shouldPostException.setNext(check); + return check; + } + } + } + } + return afterExceptionLoaded; + } + + private static final LocationIdentity JAVA_THREAD_SHOULD_POST_ON_EXCEPTIONS_FLAG_LOCATION = NamedLocationIdentity.mutable("JavaThread::_should_post_on_exceptions_flag"); + + private static final Unsafe UNSAFE = initUnsafe(); + + private static Unsafe initUnsafe() { + try { + // Fast path when we are trusted. + return Unsafe.getUnsafe(); + } catch (SecurityException se) { + // Slow path when we are not trusted. + try { + Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafe.setAccessible(true); + return (Unsafe) theUnsafe.get(Unsafe.class); + } catch (Exception e) { + throw new RuntimeException("exception while trying to get Unsafe", e); + } + } + } } diff -r 1ae823617395 -r ccfd4e614bb8 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Tue Jan 22 03:32:47 2019 -0800 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Tue Jan 22 19:56:19 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1106,7 +1106,11 @@ deopt.updateNodeSourcePosition(() -> createBytecodePosition()); } + /** + * @return the entry point to exception dispatch + */ private AbstractBeginNode handleException(ValueNode exceptionObject, int bci, boolean deoptimizeOnly) { + FixedWithNextNode currentLastInstr = lastInstr; assert bci == BytecodeFrame.BEFORE_BCI || bci == bci() : "invalid bci"; debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, (profilingInfo == null ? "" : profilingInfo.getExceptionSeen(bci))); @@ -1126,18 +1130,25 @@ dispatchState.setRethrowException(true); } this.controlFlowSplit = true; - FixedWithNextNode finishedDispatch = finishInstruction(dispatchBegin, dispatchState); + FixedWithNextNode afterExceptionLoaded = finishInstruction(dispatchBegin, dispatchState); if (deoptimizeOnly) { DeoptimizeNode deoptimizeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter)); - dispatchBegin.setNext(BeginNode.begin(deoptimizeNode)); + afterExceptionLoaded.setNext(BeginNode.begin(deoptimizeNode)); } else { - createHandleExceptionTarget(finishedDispatch, bci, dispatchState); - } + createHandleExceptionTarget(afterExceptionLoaded, bci, dispatchState); + } + assert currentLastInstr == lastInstr; return dispatchBegin; } - protected void createHandleExceptionTarget(FixedWithNextNode finishedDispatch, int bci, FrameStateBuilder dispatchState) { + protected void createHandleExceptionTarget(FixedWithNextNode afterExceptionLoaded, int bci, FrameStateBuilder dispatchState) { + FixedWithNextNode afterInstrumentation = afterExceptionLoaded; + for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) { + afterInstrumentation = plugin.instrumentExceptionDispatch(graph, afterInstrumentation); + assert afterInstrumentation.next() == null : "exception dispatch instrumentation will be linked to dispatch block"; + } + BciBlock dispatchBlock = currentBlock.exceptionDispatchBlock(); /* * The exception dispatch block is always for the last bytecode of a block, so if we are not @@ -1149,7 +1160,7 @@ } FixedNode target = createTarget(dispatchBlock, dispatchState); - finishedDispatch.setNext(target); + afterInstrumentation.setNext(target); } protected ValueNode genLoadIndexed(ValueNode array, ValueNode index, GuardingNode boundsCheck, JavaKind kind) { diff -r 1ae823617395 -r ccfd4e614bb8 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/NodePlugin.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/NodePlugin.java Tue Jan 22 03:32:47 2019 -0800 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/NodePlugin.java Tue Jan 22 19:56:19 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,9 @@ package org.graalvm.compiler.nodes.graphbuilderconf; +import org.graalvm.compiler.graph.Node.ValueNumberable; +import org.graalvm.compiler.nodes.FixedWithNextNode; +import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.extended.GuardingNode; @@ -210,6 +213,23 @@ } /** + * Allows this plugin to add nodes after the exception object has been loaded in the dispatch + * sequence. Note that a {@link StructuredGraph} is provided to this call instead of a + * {@link GraphBuilderContext} so that the caller has a guarantee that its current control flow + * insertion point is not changed by this call. This means nodes must be added to the graph with + * the appropriate method (e.g., {@link StructuredGraph#unique} for {@link ValueNumberable} + * nodes) and fixed nodes must be manually {@linkplain FixedWithNextNode#setNext added} as + * successors of {@code afterExceptionLoaded}. + * + * @param graph the graph being parsed + * @param afterExceptionLoaded the last fixed node after loading the exception + * @return the last fixed node after instrumentation + */ + default FixedWithNextNode instrumentExceptionDispatch(StructuredGraph graph, FixedWithNextNode afterExceptionLoaded) { + return afterExceptionLoaded; + } + + /** * If the plugin {@link GraphBuilderContext#push pushes} a value with a different * {@link JavaKind} than specified by the bytecode, it must override this method and return * {@code true}. This disables assertion checking for value kinds. diff -r 1ae823617395 -r ccfd4e614bb8 test/hotspot/jtreg/ProblemList-graal.txt --- a/test/hotspot/jtreg/ProblemList-graal.txt Tue Jan 22 03:32:47 2019 -0800 +++ b/test/hotspot/jtreg/ProblemList-graal.txt Tue Jan 22 19:56:19 2019 +0100 @@ -165,5 +165,3 @@ org.graalvm.compiler.hotspot.test.ReservedStackAccessTest 8213567 windows-all org.graalvm.compiler.replacements.test.StringCompressInflateTest 8213556 - -org.graalvm.compiler.debug.test.TimerKeyTest 8213598 diff -r 1ae823617395 -r ccfd4e614bb8 test/jdk/ProblemList.txt --- a/test/jdk/ProblemList.txt Tue Jan 22 03:32:47 2019 -0800 +++ b/test/jdk/ProblemList.txt Tue Jan 22 19:56:19 2019 +0100 @@ -559,9 +559,7 @@ java/net/MulticastSocket/NoLoopbackPackets.java 7122846 macosx-all java/net/MulticastSocket/SetLoopbackMode.java 7122846 macosx-all -java/net/MulticastSocket/Test.java 7145658,8207404 macosx-all,aix-all -java/net/MulticastSocket/JoinLeave.java 8207404 aix-all -java/net/MulticastSocket/SetGetNetworkInterfaceTest.java 8207404 aix-all +java/net/MulticastSocket/Test.java 7145658 macosx-all java/net/DatagramSocket/SendDatagramToBadAddress.java 7143960 macosx-all diff -r 1ae823617395 -r ccfd4e614bb8 test/jdk/java/net/MulticastSocket/JoinLeave.java --- a/test/jdk/java/net/MulticastSocket/JoinLeave.java Tue Jan 22 03:32:47 2019 -0800 +++ b/test/jdk/java/net/MulticastSocket/JoinLeave.java Tue Jan 22 19:56:19 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,15 @@ * questions. */ -/* +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.InetAddress; +import java.net.MulticastSocket; +import java.net.NetworkInterface; + +import jdk.test.lib.NetworkConfiguration; + +/** * @test * @bug 4091811 4148753 4102731 * @summary Test java.net.MulticastSocket joinGroup and leaveGroup @@ -29,18 +37,11 @@ * @build jdk.test.lib.NetworkConfiguration * jdk.test.lib.Platform * @run main JoinLeave + * @run main/othervm -Djava.net.preferIPv4Stack=true JoinLeave */ - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.net.InetAddress; -import java.net.MulticastSocket; -import java.net.NetworkInterface; -import jdk.test.lib.NetworkConfiguration; - public class JoinLeave { - public static void main(String args[]) throws IOException { + public static void main(String args[]) throws IOException { InetAddress ip4Group = InetAddress.getByName("224.80.80.80"); InetAddress ip6Group = InetAddress.getByName("ff02::a"); @@ -49,8 +50,7 @@ nc.ip6MulticastInterfaces().forEach(nic -> joinLeave(ip6Group, nic)); } - static void joinLeave(InetAddress group, NetworkInterface nif) - { + static void joinLeave(InetAddress group, NetworkInterface nif) { System.out.println("Joining:" + group + " on " + nif); try (MulticastSocket soc = new MulticastSocket()) { soc.setNetworkInterface(nif); diff -r 1ae823617395 -r ccfd4e614bb8 test/jdk/java/net/MulticastSocket/SetGetNetworkInterfaceTest.java --- a/test/jdk/java/net/MulticastSocket/SetGetNetworkInterfaceTest.java Tue Jan 22 03:32:47 2019 -0800 +++ b/test/jdk/java/net/MulticastSocket/SetGetNetworkInterfaceTest.java Tue Jan 22 19:56:19 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,105 +21,50 @@ * questions. */ +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.MulticastSocket; +import java.net.NetworkInterface; -/* +import jdk.test.lib.NetworkConfiguration; + +/** * @test * @bug 6458027 * @summary Disabling IPv6 on a specific network interface causes problems. - * - */ - -import java.io.IOException; -import java.net.InetAddress; -import java.net.MulticastSocket; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.util.Arrays; -import java.util.Enumeration; - - -public class SetGetNetworkInterfaceTest { + * @library /test/lib + * @build jdk.test.lib.NetworkConfiguration + * jdk.test.lib.Platform + * @run main SetGetNetworkInterfaceTest + * @run main/othervm -Djava.net.preferIPv4Stack=true SetGetNetworkInterfaceTest +*/ +public class SetGetNetworkInterfaceTest { public static void main(String[] args) throws Exception { - - boolean passed = true; - try { - MulticastSocket ms = new MulticastSocket(); - Enumeration networkInterfaces = NetworkInterface - .getNetworkInterfaces(); - while (networkInterfaces.hasMoreElements()) { - NetworkInterface netIf = networkInterfaces.nextElement(); - if (isNetworkInterfaceTestable(netIf)) { - printNetIfDetails(netIf); - ms.setNetworkInterface(netIf); - NetworkInterface msNetIf = ms.getNetworkInterface(); - if (netIf.equals(msNetIf)) { - System.out.println(" OK"); - } else { - System.out.println("FAILED!!!"); - printNetIfDetails(msNetIf); - passed = false; - } - System.out.println("------------------"); - } - } + NetworkConfiguration nc = NetworkConfiguration.probe(); + try (MulticastSocket ms = new MulticastSocket()) { + nc.multicastInterfaces(true).forEach(nif -> setGetNetworkInterface(ms, nif)); } catch (IOException e) { e.printStackTrace(); - passed = false; } - if (!passed) { - throw new RuntimeException("Test Fail"); - } - System.out.println("Test passed "); + System.out.println("Test passed."); } - private static boolean isNetworkInterfaceTestable(NetworkInterface netIf) throws Exception { - System.out.println("checking netif == " + netIf.getName()); - return (netIf.isUp() && netIf.supportsMulticast() && isIpAddrAvailable(netIf)); - } - - private static boolean isIpAddrAvailable (NetworkInterface netIf) { - boolean ipAddrAvailable = false; - byte[] nullIpAddr = {'0', '0', '0', '0'}; - byte[] testIpAddr = null; - - Enumeration ipAddresses = netIf.getInetAddresses(); - while (ipAddresses.hasMoreElements()) { - InetAddress testAddr = ipAddresses.nextElement(); - testIpAddr = testAddr.getAddress(); - if ((testIpAddr != null) && (!Arrays.equals(testIpAddr, nullIpAddr))) { - ipAddrAvailable = true; - break; + static void setGetNetworkInterface(MulticastSocket ms, NetworkInterface nif) { + try { + System.out.println(NetworkConfiguration.interfaceInformation(nif)); + ms.setNetworkInterface(nif); + NetworkInterface msNetIf = ms.getNetworkInterface(); + if (nif.equals(msNetIf)) { + System.out.println(" OK"); } else { - System.out.println("ignore netif " + netIf.getName()); + System.out.println("FAILED!!!"); + System.out.println(NetworkConfiguration.interfaceInformation(msNetIf)); + throw new RuntimeException("Test Fail"); } + System.out.println("------------------"); + } catch (IOException e) { + throw new UncheckedIOException(e); } - return ipAddrAvailable; - } - - private static void printNetIfDetails(NetworkInterface ni) - throws SocketException { - System.out.println("Name " + ni.getName() + " index " + ni.getIndex()); - Enumeration en = ni.getInetAddresses(); - while (en.hasMoreElements()) { - System.out.println(" InetAdress: " + en.nextElement()); - } - System.out.println("HardwareAddress: " + createMacAddrString(ni)); - System.out.println("loopback: " + ni.isLoopback() + "; pointToPoint: " - + ni.isPointToPoint() + "; virtual: " + ni.isVirtual() - + "; MTU: " + ni.getMTU()); - } - - private static String createMacAddrString(NetworkInterface netIf) - throws SocketException { - byte[] macAddr = netIf.getHardwareAddress(); - StringBuilder sb = new StringBuilder(); - if (macAddr != null) { - for (int i = 0; i < macAddr.length; i++) { - sb.append(String.format("%02X%s", macAddr[i], - (i < macAddr.length - 1) ? "-" : "")); - } - } - return sb.toString(); } } diff -r 1ae823617395 -r ccfd4e614bb8 test/jdk/java/net/MulticastSocket/Test.java --- a/test/jdk/java/net/MulticastSocket/Test.java Tue Jan 22 03:32:47 2019 -0800 +++ b/test/jdk/java/net/MulticastSocket/Test.java Tue Jan 22 19:56:19 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,25 +21,31 @@ * questions. */ -/* +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.MulticastSocket; +import java.net.SocketTimeoutException; + +import jdk.test.lib.NetworkConfiguration; + +/** * @test * @bug 4488458 * @summary IPv4 and IPv6 multicasting broken on Linux + * @library /test/lib + * @build jdk.test.lib.NetworkConfiguration + * jdk.test.lib.Platform + * @run main Test + * @run main/othervm -Djava.net.preferIPv4Stack=true Test */ -import java.net.*; -import java.io.IOException; -import java.util.Enumeration; - public class Test { static int count = 0; static int failures = 0; - static boolean isSolaris = System.getProperty("os.name") - .toLowerCase() - .startsWith("sunos"); - - void doTest(String address) throws Exception { + void doTest(String address) throws IOException { boolean failed = false; InetAddress ia = InetAddress.getByName(address); @@ -65,7 +71,7 @@ /* packets should be received */ - for (int j=0; j<2; j++) { + for (int j = 0; j < 2; j++) { p.setAddress(ia); p.setPort(port); @@ -127,67 +133,26 @@ } } - static boolean isValidIpv6Address(InetAddress addr) { - if (! (addr instanceof Inet6Address)) - return false; - if (!isSolaris) - return true; - return !(addr.isAnyLocalAddress() || addr.isLoopbackAddress()); - } + void allTests() throws IOException { + NetworkConfiguration nc = NetworkConfiguration.probe(); - void allTests() throws Exception { - - /* - * Assume machine has IPv4 address - */ + // unconditionally test IPv4 address doTest("224.80.80.80"); - /* - * Check if IPv6 is enabled and the scope of the addresses - */ - boolean has_ipv6 = false; - boolean has_siteaddress = false; - boolean has_linklocaladdress = false; - boolean has_globaladdress = false; - - Enumeration nifs = NetworkInterface.getNetworkInterfaces(); - while (nifs.hasMoreElements()) { - NetworkInterface ni = (NetworkInterface)nifs.nextElement(); - Enumeration addrs = ni.getInetAddresses(); - - while (addrs.hasMoreElements()) { - InetAddress ia = (InetAddress)addrs.nextElement(); - - if (isValidIpv6Address(ia)) { - has_ipv6 = true; - if (ia.isLinkLocalAddress()) has_linklocaladdress = true; - if (ia.isSiteLocalAddress()) has_siteaddress = true; - - if (!ia.isLinkLocalAddress() && - !ia.isSiteLocalAddress() && - !ia.isLoopbackAddress()) { - has_globaladdress = true; - } - } - } - } - - /* - * If IPv6 is enabled perform multicast tests with various scopes - */ - if (has_ipv6) { + // If IPv6 is enabled perform multicast tests with various scopes + if (nc.hasTestableIPv6Address()) { doTest("ff01::a"); } - if (has_linklocaladdress) { + if (nc.hasLinkLocalAddress()) { doTest("ff02::a"); } - if (has_siteaddress) { + if (nc.hasSiteLocalAddress()) { doTest("ff05::a"); } - if (has_globaladdress) { + if (nc.has_globaladdress()) { doTest("ff0e::a"); } } @@ -198,7 +163,7 @@ if (args.length == 0) { t.allTests(); } else { - for (int i=0; i-chain.pem". + private static String[] subCAsToTest = new String[] { + "appleistca2g1", "appleistca8g1" }; + // A date that is after the restrictions take affect private static final Date APRIL_17_2019 = Date.from(LocalDate.of(2019, 4, 17) .atStartOfDay(ZoneOffset.UTC) .toInstant()); + // A date that is a second before the restrictions take affect + private static final Date BEFORE_APRIL_17_2019 = + Date.from(LocalDate.of(2019, 4, 17) + .atStartOfDay(ZoneOffset.UTC) + .minusSeconds(1) + .toInstant()); + + // A date that is after the subCA restrictions take affect + private static final Date JANUARY_1_2020 = + Date.from(LocalDate.of(2020, 1, 1) + .atStartOfDay(ZoneOffset.UTC) + .toInstant()); + + // A date that is a second before the subCA restrictions take affect + private static final Date BEFORE_JANUARY_1_2020 = + Date.from(LocalDate.of(2020, 1, 1) + .atStartOfDay(ZoneOffset.UTC) + .minusSeconds(1) + .toInstant()); + public static void main(String[] args) throws Exception { cf = CertificateFactory.getInstance("X.509"); - boolean distrust = args[0].equals("true"); - if (!distrust) { - // disable policy + + boolean before = args[0].equals("before"); + boolean policyOn = args[1].equals("policyOn"); + boolean isValid = args[2].equals("valid"); + + if (!policyOn) { + // disable policy (default is on) Security.setProperty("jdk.security.caDistrustPolicies", ""); } + Date notBefore = before ? BEFORE_APRIL_17_2019 : APRIL_17_2019; + X509TrustManager pkixTM = getTMF("PKIX", null); X509TrustManager sunX509TM = getTMF("SunX509", null); for (String test : rootsToTest) { System.err.println("Testing " + test); X509Certificate[] chain = loadCertificateChain(test); - testTM(sunX509TM, chain, !distrust); - testTM(pkixTM, chain, !distrust); + testTM(sunX509TM, chain, notBefore, isValid); + testTM(pkixTM, chain, notBefore, isValid); } // test chain if params are passed to TrustManager System.err.println("Testing verisignuniversalrootca with params"); testTM(getTMF("PKIX", getParams()), - loadCertificateChain("verisignuniversalrootca"), !distrust); + loadCertificateChain("verisignuniversalrootca"), + notBefore, isValid); // test code-signing chain (should be valid as restrictions don't apply) System.err.println("Testing verisignclass3g5ca code-signing chain"); @@ -95,6 +129,16 @@ // set validation date so this will still pass when cert expires v.setValidationDate(new Date(1544197375493l)); v.validate(loadCertificateChain("verisignclass3g5ca-codesigning")); + + // test chains issued through subCAs + notBefore = before ? BEFORE_JANUARY_1_2020 : JANUARY_1_2020; + for (String test : subCAsToTest) { + System.err.println("Testing " + test); + X509Certificate[] chain = loadCertificateChain(test); + + testTM(sunX509TM, chain, notBefore, isValid); + testTM(pkixTM, chain, notBefore, isValid); + } } private static X509TrustManager getTMF(String type, @@ -122,12 +166,13 @@ } private static void testTM(X509TrustManager xtm, X509Certificate[] chain, - boolean valid) throws Exception { + Date notBefore, boolean valid) throws Exception { // Check if TLS Server certificate (the first element of the chain) - // is issued after April 16, 2019 (should be rejected unless distrust - // property is false). To do this, we need to fake the notBefore date - // since none of the test certs are issued after then. - chain[0] = new DistrustedTLSServerCert(chain[0], APRIL_17_2019); + // is issued after the specified notBefore date (should be rejected + // unless distrust property is false). To do this, we need to + // fake the notBefore date since none of the test certs are issued + // after then. + chain[0] = new DistrustedTLSServerCert(chain[0], notBefore); try { xtm.checkServerTrusted(chain, "ECDHE_RSA"); diff -r 1ae823617395 -r ccfd4e614bb8 test/jdk/sun/security/ssl/X509TrustManagerImpl/Symantec/appleistca2g1-chain.pem --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/sun/security/ssl/X509TrustManagerImpl/Symantec/appleistca2g1-chain.pem Tue Jan 22 19:56:19 2019 +0100 @@ -0,0 +1,80 @@ +-----BEGIN CERTIFICATE----- +MIIGGzCCBQOgAwIBAgIITJltLCqcD0gwDQYJKoZIhvcNAQELBQAwYjEcMBoGA1UE +AxMTQXBwbGUgSVNUIENBIDIgLSBHMTEgMB4GA1UECxMXQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkxEzARBgNVBAoTCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMB4XDTE5 +MDEwODIxMTcxNFoXDTIwMDgwODIxMjcwMFowgaoxSjBIBgNVBAMMQWFjdGl2ZS5n +ZW90cnVzdC1nbG9iYWwtY2EudGVzdC1wYWdlcy5jZXJ0aWZpY2F0ZW1hbmFnZXIu +YXBwbGUuY29tMSUwIwYDVQQLDBxtYW5hZ2VtZW50OmlkbXMuZ3JvdXAuODY0ODU5 +MRMwEQYDVQQKDApBcHBsZSBJbmMuMRMwEQYDVQQIDApDYWxpZm9ybmlhMQswCQYD +VQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMCjFUrVHTEX +0aVU6x9LiGa6oVr9blaCsMFrLicPQguc43Vs/pN+g4jzRXsTSMe9XefezBQb6tzZ +SMRXVB4kWMr4K1BVgQDkXeyoh4KrXRkdEF9ZIJPNxwTmmYUOc5M6NOYwkLelYz+t +7n1iNIGylbjwU4qwauElk2alFVqYTEPDLzwvqVDb9jMAJ8MPSDjfUlXW0XD9oXZM +hC+8LU9JBgJ3YBdzRHa4WnrudUbWjspqaNfAYpVIX0cfCJKnMsKqaSKjS4pIRtWm +L6NlCTCoIMyOh+wmbWPPX24H2D3+ump5FA35fRYbVznmosl5n1AK34S9tD4XZ7lO +WZKfaFi1liMCAwEAAaOCAoowggKGMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU +2HqURHyQcJAWnt0XnAFEA4bWKikwfgYIKwYBBQUHAQEEcjBwMDQGCCsGAQUFBzAC +hihodHRwOi8vY2VydHMuYXBwbGUuY29tL2FwcGxlaXN0Y2EyZzEuZGVyMDgGCCsG +AQUFBzABhixodHRwOi8vb2NzcC5hcHBsZS5jb20vb2NzcDAzLWFwcGxlaXN0Y2Ey +ZzEwMTBMBgNVHREERTBDgkFhY3RpdmUuZ2VvdHJ1c3QtZ2xvYmFsLWNhLnRlc3Qt +cGFnZXMuY2VydGlmaWNhdGVtYW5hZ2VyLmFwcGxlLmNvbTCB/wYDVR0gBIH3MIH0 +MIHxBgoqhkiG92NkBQsEMIHiMIGkBggrBgEFBQcCAjCBlwyBlFJlbGlhbmNlIG9u +IHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0YW5j +ZSBvZiBhbnkgYXBwbGljYWJsZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2Ug +YW5kL29yIGNlcnRpZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wOQYIKwYB +BQUHAgEWLWh0dHA6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5 +L3JwYTAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwNwYDVR0fBDAwLjAs +oCqgKIYmaHR0cDovL2NybC5hcHBsZS5jb20vYXBwbGVpc3RjYTJnMS5jcmwwHQYD +VR0OBBYEFP0qkmFJhArI0MsfW0V+/wY9x4GSMA4GA1UdDwEB/wQEAwIFoDANBgkq +hkiG9w0BAQsFAAOCAQEATjT8M0bIq+mFc8k5cd4KDjCMBjYl/l3/8zKlWYGP+nl1 +KRogXcGRa3LcfpdJcqgMrx8e9Xohduvl8MBzwv671rYkppzZdsmZdLVorAdbL5GL +suhTjAS5yL3NBWNMRpeOgFsVr7YtPDEvo3CFsnzjg7THe0S6Y35oYukJtUzGUvSY +kC3ApBTdjj0vAeow+dbt+AHKnQiEnon4ToSFmtnkru08Uxe7uyHCQ2sLUg0EPYc9 +t9I8lviaHfK/mQoCzlme2O/H5Rher8dXCv8hVT1NKbsi28EpgpqcTLS+hn/Edc/q +4dPDoO1Ozs+ixRzFeMpA+JrnAyARb6qbSrAPBgtIbQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEQDCCAyigAwIBAgIDAjp0MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMTQwNjE2MTU0MjAyWhcNMjIwNTIwMTU0MjAyWjBiMRwwGgYDVQQD +ExNBcHBsZSBJU1QgQ0EgMiAtIEcxMSAwHgYDVQQLExdDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTETMBEGA1UEChMKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQk6EdR0MgFrILa+vD1bTox5jN896/ +6E3p4zaAB/xFG2p8RYauVtOkCX9hDWtdflJrfbTIOcT0Zzr3g84Zb4YvfkV+Rxxn +UsqVBV3iNlGFwNRngDVvFd0+/R3S/Y80UNjsdiq+49Pa5P3I6ygClhGXF2Ec6cRZ +O0LcMtEJHdqm0UOG/16yvIzPZtsBiwKulEjzOI/96jKoCOyGl1GUJD5JSZZT6Hmh +QIHpBbuTlVH84/18EUv3ngizFUkVB/nRN6CbSzL2tcTcatH8Cu324MUpoKiLcf4N +krz+VHAYCm3H7Qz7yS0Gw4yF/MuGXNY2jhKLCX/7GRo41fCUMHoPpozzAgMBAAGj +ggEdMIIBGTAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1luMrMTjAdBgNVHQ4E +FgQU2HqURHyQcJAWnt0XnAFEA4bWKikwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNV +HQ8BAf8EBAMCAQYwNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2cuc3ltY2IuY29t +L2NybHMvZ3RnbG9iYWwuY3JsMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYS +aHR0cDovL2cuc3ltY2QuY29tMEwGA1UdIARFMEMwQQYKYIZIAYb4RQEHNjAzMDEG +CCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvY3Bz +MA0GCSqGSIb3DQEBCwUAA4IBAQAWR3NvhaJi4ecqdruJlUIml7xKrKxwUzo/MYM9 +PByrmuKxXRx2GqA8DHJXvtOeUODImdZY1wLqzg0pVHzN9cLGkClVo28UqAtCDTqY +bQZ4nvBqox0CCqIopI3CgUY+bWfa3j/+hQ5CKhLetbf7uBunlux3n+zUU5V6/wf0 +8goUwFFSsdaOUAsamVy8C8m97e34XsFW201+I6QRoSzUGwWa5BtS9nw4mQVLunKN +QolgBGYq9P1o12v3mUEo1mwkq+YlUy7Igpnioo8jvjCDsSeL+mh/AUnoxphrEC6Y +XorXykuxx8lYmtA225aV7LaB5PLNbxt5h0wQPInkTfpU3Kqm +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg +R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 +9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq +fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv +iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU +1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ +bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW +MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA +ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l +uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn +Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS +tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF +PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un +hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV +5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== +-----END CERTIFICATE----- diff -r 1ae823617395 -r ccfd4e614bb8 test/jdk/sun/security/ssl/X509TrustManagerImpl/Symantec/appleistca8g1-chain.pem --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/sun/security/ssl/X509TrustManagerImpl/Symantec/appleistca8g1-chain.pem Tue Jan 22 19:56:19 2019 +0100 @@ -0,0 +1,64 @@ +-----BEGIN CERTIFICATE----- +MIIElDCCBDqgAwIBAgIIWax3IY1ByGIwCgYIKoZIzj0EAwIwYjEcMBoGA1UEAwwT +QXBwbGUgSVNUIENBIDggLSBHMTEgMB4GA1UECwwXQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMB4XDTE5MDEw +ODIxMTAyNFoXDTIwMDgwODIxMjAwMFowga0xTTBLBgNVBAMMRGFjdGl2ZS5nZW90 +cnVzdC1nbG9iYWwtY2EtZzIudGVzdC1wYWdlcy5jZXJ0aWZpY2F0ZW1hbmFnZXIu +YXBwbGUuY29tMSUwIwYDVQQLDBxtYW5hZ2VtZW50OmlkbXMuZ3JvdXAuODY0ODU5 +MRMwEQYDVQQKDApBcHBsZSBJbmMuMRMwEQYDVQQIDApDYWxpZm9ybmlhMQswCQYD +VQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABN4oxNLGzmOIfgFRxDaU +SaOYTQVZCc7a7MXlK1L4/KgN22stgSkrg47aOWviMuzb9Q9hDA/Tn19o9Zr8G5ON +pYijggKMMIICiDAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFMPEpFgFY9eDBrqW +jdyyjzL2u7dBMH4GCCsGAQUFBwEBBHIwcDA0BggrBgEFBQcwAoYoaHR0cDovL2Nl +cnRzLmFwcGxlLmNvbS9hcHBsZWlzdGNhOGcxLmRlcjA4BggrBgEFBQcwAYYsaHR0 +cDovL29jc3AuYXBwbGUuY29tL29jc3AwMy1hcHBsZWlzdGNhOGcxMDEwTwYDVR0R +BEgwRoJEYWN0aXZlLmdlb3RydXN0LWdsb2JhbC1jYS1nMi50ZXN0LXBhZ2VzLmNl +cnRpZmljYXRlbWFuYWdlci5hcHBsZS5jb20wgf4GA1UdIASB9jCB8zCB8AYKKoZI +hvdjZAULBDCB4TCBpAYIKwYBBQUHAgIwgZcMgZRSZWxpYW5jZSBvbiB0aGlzIGNl +cnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgYW55 +IGFwcGxpY2FibGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdXNlIGFuZC9vciBj +ZXJ0aWZpY2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMDgGCCsGAQUFBwICMCwM +Kmh0dHA6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5LzAdBgNV +HSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwNwYDVR0fBDAwLjAsoCqgKIYmaHR0 +cDovL2NybC5hcHBsZS5jb20vYXBwbGVpc3RjYThnMS5jcmwwHQYDVR0OBBYEFCQy +hU8U00tcIz6L0MCT6EGVho0EMA4GA1UdDwEB/wQEAwIDiDAKBggqhkjOPQQDAgNI +ADBFAiAl5nGHi2u8V0aJSp4o1i3TlK7ao8WvxwBuHKfuKibSLAIhAN8PZqhESS9u +V7Dr6qzs88yn/1z6oeqPwDsntFpUFtWG +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDVDCCAtugAwIBAgIQE1Iuv8HdXOEe8nZAdR/n3zAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTE2MDYwOTAwMDAwMFoXDTMxMDYwODIzNTk1OVowYjEcMBoGA1UE +AwwTQXBwbGUgSVNUIENBIDggLSBHMTEgMB4GA1UECwwXQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMFkwEwYH +KoZIzj0CAQYIKoZIzj0DAQcDQgAELVSOaLAQE+/0LdvYCbJD6J1lmW40uNSXyY7J +1qgiNzLIcWDusPHyxWT2ukdf/OYHeDIt9sqAIMn9cPhykyGIRaOCATowggE2MBIG +A1UdEwEB/wQIMAYBAf8CAQAwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2cuc3lt +Y2IuY29tL0dlb1RydXN0UENBLUcyLmNybDAOBgNVHQ8BAf8EBAMCAQYwLgYIKwYB +BQUHAQEEIjAgMB4GCCsGAQUFBzABhhJodHRwOi8vZy5zeW1jZC5jb20wSQYDVR0g +BEIwQDA+BgZngQwBAgIwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2VvdHJ1 +c3QuY29tL3Jlc291cmNlcy9jcHMwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF +BwMCMB0GA1UdDgQWBBTDxKRYBWPXgwa6lo3cso8y9ru3QTAfBgNVHSMEGDAWgBQV +XzVXUVX7JbKtA2n8AaP6vhFV1TAKBggqhkjOPQQDAwNnADBkAjBH2jMNybjCk3Ts +OidXxJX9YDPMd5S3KDCv8vyTdJGhtoly7fQJRNv5rnVz+6YGfsMCMEp6wyheL7NK +mqavsduix2R+j1B3wRjelzJYgXzgM3nwhQKKlJWxpF7IGHuva1taxg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +rD6ogRLQy7rQkgu2npaqBA+K +-----END CERTIFICATE----- diff -r 1ae823617395 -r ccfd4e614bb8 test/lib/jdk/test/lib/NetworkConfiguration.java --- a/test/lib/jdk/test/lib/NetworkConfiguration.java Tue Jan 22 03:32:47 2019 -0800 +++ b/test/lib/jdk/test/lib/NetworkConfiguration.java Tue Jan 22 19:56:19 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,9 +23,9 @@ package jdk.test.lib; +import java.io.IOException; import java.io.PrintStream; import java.io.UncheckedIOException; -import java.io.IOException; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; @@ -35,9 +35,9 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; + import static java.net.NetworkInterface.getNetworkInterfaces; import static java.util.Collections.list; @@ -49,12 +49,140 @@ private Map> ip4Interfaces; private Map> ip6Interfaces; + private final boolean isIPv6Available; + private boolean has_testableipv6address = false; + private boolean has_sitelocaladdress = false; + private boolean has_linklocaladdress = false; + private boolean has_globaladdress = false; private NetworkConfiguration( Map> ip4Interfaces, Map> ip6Interfaces) { this.ip4Interfaces = ip4Interfaces; this.ip6Interfaces = ip6Interfaces; + + // initialize properties that can be queried + isIPv6Available = !ip6Interfaces().collect(Collectors.toList()).isEmpty(); + ip6Interfaces().forEach(nif -> { + ip6Addresses(nif) + // On Solaris or AIX, a configuration with only local or loopback + // addresses does not fully enable IPv6 operations. + // E.g. IPv6 multicasting does not work. + // So, don't set has_testableipv6address if we only find these. + .filter(addr -> Platform.isSolaris() || Platform.isAix() ? + !(addr.isAnyLocalAddress() || addr.isLoopbackAddress()) : true) + .forEach(ia -> { + has_testableipv6address = true; + if (ia.isLinkLocalAddress()) has_linklocaladdress = true; + if (ia.isSiteLocalAddress()) has_sitelocaladdress = true; + + if (!ia.isLinkLocalAddress() && + !ia.isSiteLocalAddress() && + !ia.isLoopbackAddress()) { + has_globaladdress = true; + } + }); + }); + } + + private static boolean isNotExcludedInterface(NetworkInterface nif) { + if (Platform.isOSX() && nif.getName().contains("awdl")) { + return false; + } + if (Platform.isWindows()) { + String dName = nif.getDisplayName(); + if (dName != null && dName.contains("Teredo")) { + return false; + } + } + return true; + } + + private static boolean isNotLoopback(NetworkInterface nif) { + try { + return !nif.isLoopback(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + private boolean hasIp4Addresses(NetworkInterface nif) { + return ip4Interfaces.get(nif).stream().anyMatch(a -> !a.isAnyLocalAddress()); + } + + private boolean hasIp6Addresses(NetworkInterface nif) { + return ip6Interfaces.get(nif).stream().anyMatch(a -> !a.isAnyLocalAddress()); + } + + private boolean supportsIp4Multicast(NetworkInterface nif) { + try { + if (!nif.supportsMulticast()) { + return false; + } + + // On AIX there is a bug: + // When IPv6 is enabled on the system, the JDK opens sockets as AF_INET6. + // If there's an interface configured with IPv4 addresses only, it should + // be able to become the network interface for a multicast socket (that + // could be in both, IPv4 or IPv6 space). But both possible setsockopt + // calls for either IPV6_MULTICAST_IF or IP_MULTICAST_IF return + // EADDRNOTAVAIL. So we must skip such interfaces here. + if (Platform.isAix() && isIPv6Available() && !hasIp6Addresses(nif)) { + return false; + } + + return hasIp4Addresses(nif); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + private boolean supportsIp6Multicast(NetworkInterface nif) { + try { + if (!nif.supportsMulticast()) { + return false; + } + + return hasIp6Addresses(nif); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + /** + * Returns whether IPv6 is available at all. + * This should resemble the result of native ipv6_available() in net_util.c + */ + public boolean isIPv6Available() { + return isIPv6Available; + } + + /** + * Does any (usable) IPv6 address exist in the network configuration? + */ + public boolean hasTestableIPv6Address() { + return has_testableipv6address; + } + + /** + * Does any site local address exist? + */ + public boolean hasSiteLocalAddress() { + return has_sitelocaladdress; + } + + /** + * Does any link local address exist? + */ + public boolean hasLinkLocalAddress() { + return has_linklocaladdress; + } + + /** + * Does any global IPv6 address exist? + */ + public boolean has_globaladdress() { + return has_globaladdress; } /** @@ -72,7 +200,7 @@ return ip4Interfaces.keySet() .stream() .filter(NetworkConfiguration::isNotExcludedInterface) - .filter(hasIp4Addresses); + .filter(this::hasIp4Addresses); } /** @@ -82,64 +210,57 @@ return ip6Interfaces.keySet() .stream() .filter(NetworkConfiguration::isNotExcludedInterface) - .filter(hasIp6Addresses); + .filter(this::hasIp6Addresses); } - private static boolean isNotExcludedInterface(NetworkInterface nif) { - if (Platform.isOSX() && nif.getName().contains("awdl")) { - return false; - } - String dName = nif.getDisplayName(); - if (Platform.isWindows() && dName != null && dName.contains("Teredo")) { - return false; - } - return true; + /** + * Returns a stream of interfaces suitable for functional tests. + */ + public Stream multicastInterfaces(boolean includeLoopback) { + return Stream + .concat(ip4MulticastInterfaces(includeLoopback), + ip6MulticastInterfaces(includeLoopback)) + .distinct(); } - private final Predicate hasIp4Addresses = nif -> - ip4Interfaces.get(nif).stream().anyMatch(a -> !a.isAnyLocalAddress()); - - private final Predicate hasIp6Addresses = nif -> - ip6Interfaces.get(nif).stream().anyMatch(a -> !a.isAnyLocalAddress()); - + /** + * Returns a stream of interfaces suitable for IPv4 multicast tests. + * + * The loopback interface will not be included. + */ + public Stream ip4MulticastInterfaces() { + return ip4MulticastInterfaces(false); + } /** * Returns a stream of interfaces suitable for IPv4 multicast tests. */ - public Stream ip4MulticastInterfaces() { - return ip4Interfaces().filter(supportsIp4Multicast); + public Stream ip4MulticastInterfaces(boolean includeLoopback) { + return (includeLoopback) ? + ip4Interfaces().filter(this::supportsIp4Multicast) : + ip4Interfaces().filter(this::supportsIp4Multicast) + .filter(NetworkConfiguration::isNotLoopback); + } + + /** + * Returns a stream of interfaces suitable for IPv6 multicast tests. + * + * The loopback interface will not be included. + */ + public Stream ip6MulticastInterfaces() { + return ip6MulticastInterfaces(false); } /** * Returns a stream of interfaces suitable for IPv6 multicast tests. */ - public Stream ip6MulticastInterfaces() { - return ip6Interfaces().filter(supportsIp6Multicast); + public Stream ip6MulticastInterfaces(boolean includeLoopback) { + return (includeLoopback) ? + ip6Interfaces().filter(this::supportsIp6Multicast) : + ip6Interfaces().filter(this::supportsIp6Multicast) + .filter(NetworkConfiguration::isNotLoopback); } - private final Predicate supportsIp4Multicast = nif -> { - try { - if (!nif.supportsMulticast() || nif.isLoopback()) { - return false; - } - return hasIp4Addresses.test(nif); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - }; - - private final Predicate supportsIp6Multicast = nif -> { - try { - if (!nif.supportsMulticast() || nif.isLoopback()) { - return false; - } - - return hasIp6Addresses.test(nif); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - }; - /** * Returns all addresses on all "functional" interfaces. */ @@ -176,6 +297,12 @@ return ip6Interfaces.get(nif).stream(); } + @Override + public String toString() { + return interfaces().map(NetworkConfiguration::interfaceInformation) + .collect(Collectors.joining()); + } + /** * Return a NetworkConfiguration instance. */ @@ -205,12 +332,6 @@ return new NetworkConfiguration(ip4Interfaces, ip6Interfaces); } - @Override - public String toString() { - return interfaces().map(NetworkConfiguration::interfaceInformation) - .collect(Collectors.joining()); - } - /** Returns detailed information for the given interface. */ public static String interfaceInformation(NetworkInterface nif) { StringBuilder sb = new StringBuilder();