This commit is contained in:
Jesper Wilhelmsson 2019-01-22 19:56:19 +01:00
commit bc920bd00d
25 changed files with 736 additions and 320 deletions

View File

@ -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 @@ JVMCIEnv::JVMCIEnv(CompileTask* task, int system_dictionary_modification_counter
{
// 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 @@ methodHandle JVMCIEnv::get_method_by_index(const constantPoolHandle& cpool,
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

View File

@ -105,10 +105,13 @@ private:
// 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 @@ private:
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; }

View File

@ -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) \
\

View File

@ -2188,13 +2188,16 @@ bool Compile::optimize_loops(PhaseIterGVN& igvn, LoopOptsMode mode) {
// 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 @@ void Compile::Optimize() {
// 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

View File

@ -1088,7 +1088,7 @@ class Compile : public Phase {
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; }

View File

@ -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 @@ import sun.security.util.Debug;
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 @@ enum CADistrustPolicy {
* 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<CADistrustPolicy> POLICIES = parseProperty();

View File

@ -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 @@ class EndEntityChecker {
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<String> exts = getCriticalExtensions(cert);
Set<String> 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 @@ class EndEntityChecker {
// 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);
}
}

View File

@ -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.LocalDate;
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 @@ final class SymantecTLSPolicy {
"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<String, LocalDate> 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 @@ final class SymantecTLSPolicy {
* 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);
}
}

View File

@ -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 @@ public abstract class Validator {
// 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;

View File

@ -1167,8 +1167,15 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep
# 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

View File

@ -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 class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
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");

View File

@ -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 @@ public class HotSpotGraphBuilderPlugins {
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);

View File

@ -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.ResolvedJavaField;
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:
* <p>
* {@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:
* <ul>
* <li>{@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.
* <p>
* Constant folding of field loads.
* i.e., there are never non-inlined invokes that involve the {@link Word} type.</li>
* <li>Constant folding of field loads.</li>
* </ul>
*/
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 @@ public final class HotSpotNodePlugin implements NodePlugin, TypePlugin {
}
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);
}
}
}
}

View File

@ -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 @@ public class BytecodeParser implements GraphBuilderContext {
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 @@ public class BytecodeParser implements GraphBuilderContext {
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 @@ public class BytecodeParser implements GraphBuilderContext {
}
FixedNode target = createTarget(dispatchBlock, dispatchState);
finishedDispatch.setNext(target);
afterInstrumentation.setNext(target);
}
protected ValueNode genLoadIndexed(ValueNode array, ValueNode index, GuardingNode boundsCheck, JavaKind kind) {

View File

@ -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;
@ -209,6 +212,23 @@ public interface NodePlugin extends GraphBuilderPlugin {
return false;
}
/**
* 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

View File

@ -165,5 +165,3 @@ org.graalvm.compiler.hotspot.test.GraalOSRTest 8206947
org.graalvm.compiler.hotspot.test.ReservedStackAccessTest 8213567 windows-all
org.graalvm.compiler.replacements.test.StringCompressInflateTest 8213556
org.graalvm.compiler.debug.test.TimerKeyTest 8213598

View File

@ -559,9 +559,7 @@ javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java 8042215
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

View File

@ -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 @@ public class JoinLeave {
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);

View File

@ -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<NetworkInterface> 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<InetAddress> 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<InetAddress> 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();
}
}

View File

@ -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 @@ public class Test {
/* 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 @@ public class Test {
}
}
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 @@ public class Test {
if (args.length == 0) {
t.allTests();
} else {
for (int i=0; i<args.length; i++) {
for (int i = 0; i < args.length; i++) {
t.doTest(args[i]);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 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,8 @@
/* @test
* @bug 6435300
* @summary Check using IPv6 address does not crash the VM
* @run main/othervm UseDGWithIPv6
* @run main/othervm -Djava.net.preferIPv4Stack=true UseDGWithIPv6
*/
import java.io.IOException;
@ -31,6 +33,7 @@ import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.UnsupportedAddressTypeException;
public class UseDGWithIPv6 {
static String[] targets = {
@ -57,6 +60,8 @@ public class UseDGWithIPv6 {
try {
int n = dgChannel.send(data, sa);
System.out.println("DG_Sent " + n + " bytes");
} catch (UnsupportedAddressTypeException e) {
System.out.println("Ignoring unsupported address type");
} catch (IOException e) {
//This regression test is to check vm crash only, so ioe is OK.
e.printStackTrace();

View File

@ -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
@ -35,13 +35,15 @@ import jdk.test.lib.security.SecurityUtils;
/**
* @test
* @bug 8207258
* @bug 8207258 8216280
* @summary Check that TLS Server certificates chaining back to distrusted
* Symantec roots are invalid
* @library /test/lib
* @modules java.base/sun.security.validator
* @run main/othervm Distrust true
* @run main/othervm Distrust false
* @run main/othervm Distrust after policyOn invalid
* @run main/othervm Distrust after policyOff valid
* @run main/othervm Distrust before policyOn valid
* @run main/othervm Distrust before policyOff valid
*/
public class Distrust {
@ -57,35 +59,67 @@ public class Distrust {
"thawteprimaryrootcag3", "verisignclass3g3ca", "verisignclass3g4ca",
"verisignclass3g5ca", "verisignuniversalrootca" };
// Each of the subCAs with a delayed distrust date have a test certificate
// chain stored in a file named "<subCA>-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 @@ public class Distrust {
// 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 @@ public class Distrust {
}
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");

View File

@ -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-----

View File

@ -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-----

View File

@ -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.HashMap;
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 @@ public class NetworkConfiguration {
private Map<NetworkInterface,List<Inet4Address>> ip4Interfaces;
private Map<NetworkInterface,List<Inet6Address>> 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<NetworkInterface,List<Inet4Address>> ip4Interfaces,
Map<NetworkInterface,List<Inet6Address>> 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 @@ public class NetworkConfiguration {
return ip4Interfaces.keySet()
.stream()
.filter(NetworkConfiguration::isNotExcludedInterface)
.filter(hasIp4Addresses);
.filter(this::hasIp4Addresses);
}
/**
@ -82,64 +210,57 @@ public class NetworkConfiguration {
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<NetworkInterface> multicastInterfaces(boolean includeLoopback) {
return Stream
.concat(ip4MulticastInterfaces(includeLoopback),
ip6MulticastInterfaces(includeLoopback))
.distinct();
}
private final Predicate<NetworkInterface> hasIp4Addresses = nif ->
ip4Interfaces.get(nif).stream().anyMatch(a -> !a.isAnyLocalAddress());
private final Predicate<NetworkInterface> 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<NetworkInterface> ip4MulticastInterfaces() {
return ip4MulticastInterfaces(false);
}
/**
* Returns a stream of interfaces suitable for IPv4 multicast tests.
*/
public Stream<NetworkInterface> ip4MulticastInterfaces() {
return ip4Interfaces().filter(supportsIp4Multicast);
public Stream<NetworkInterface> 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<NetworkInterface> ip6MulticastInterfaces() {
return ip6MulticastInterfaces(false);
}
/**
* Returns a stream of interfaces suitable for IPv6 multicast tests.
*/
public Stream<NetworkInterface> ip6MulticastInterfaces() {
return ip6Interfaces().filter(supportsIp6Multicast);
public Stream<NetworkInterface> ip6MulticastInterfaces(boolean includeLoopback) {
return (includeLoopback) ?
ip6Interfaces().filter(this::supportsIp6Multicast) :
ip6Interfaces().filter(this::supportsIp6Multicast)
.filter(NetworkConfiguration::isNotLoopback);
}
private final Predicate<NetworkInterface> supportsIp4Multicast = nif -> {
try {
if (!nif.supportsMulticast() || nif.isLoopback()) {
return false;
}
return hasIp4Addresses.test(nif);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
};
private final Predicate<NetworkInterface> 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 @@ public class NetworkConfiguration {
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 @@ public class NetworkConfiguration {
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();