diff --git a/common/src/main/java/io/netty/util/internal/PlatformDependent.java b/common/src/main/java/io/netty/util/internal/PlatformDependent.java index 91a265b30e..b7ce81484f 100644 --- a/common/src/main/java/io/netty/util/internal/PlatformDependent.java +++ b/common/src/main/java/io/netty/util/internal/PlatformDependent.java @@ -15,6 +15,7 @@ */ package io.netty.util.internal; +import io.netty.util.CharsetUtil; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; import org.jctools.queues.MpscArrayQueue; @@ -28,19 +29,28 @@ import org.jctools.queues.atomic.SpscLinkedAtomicQueue; import org.jctools.util.Pow2; import org.jctools.util.UnsafeAccess; +import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Arrays; +import java.util.Collections; import java.util.Deque; +import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Queue; import java.util.Random; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.ConcurrentMap; @@ -97,6 +107,10 @@ public final class PlatformDependent { private static final String NORMALIZED_ARCH = normalizeArch(SystemPropertyUtil.get("os.arch", "")); private static final String NORMALIZED_OS = normalizeOs(SystemPropertyUtil.get("os.name", "")); + // keep in sync with maven's pom.xml via os.detection.classifierWithLikes! + private static final String[] ALLOWED_LINUX_OS_CLASSIFIERS = {"fedora", "suse", "arch"}; + private static final Set LINUX_OS_CLASSIFIERS; + private static final int ADDRESS_SIZE = addressSize0(); private static final boolean USE_DIRECT_BUFFER_NO_CLEANER; private static final AtomicLong DIRECT_MEMORY_COUNTER; @@ -196,6 +210,50 @@ public final class PlatformDependent { "Unless explicitly requested, heap buffer will always be preferred to avoid potential system " + "instability."); } + + // For specifications, see https://www.freedesktop.org/software/systemd/man/os-release.html + final String[] OS_RELEASE_FILES = {"/etc/os-release", "/usr/lib/os-release"}; + final String LINUX_ID_PREFIX = "ID="; + final String LINUX_ID_LIKE_PREFIX = "ID_LIKE="; + Set allowedClassifiers = new HashSet(Arrays.asList(ALLOWED_LINUX_OS_CLASSIFIERS)); + allowedClassifiers = Collections.unmodifiableSet(allowedClassifiers); + Set availableClassifiers = new LinkedHashSet(); + + for (String osReleaseFileName : OS_RELEASE_FILES) { + final File file = new File(osReleaseFileName); + if (file.exists()) { + BufferedReader reader = null; + try { + reader = new BufferedReader( + new InputStreamReader( + new FileInputStream(file), CharsetUtil.UTF_8)); + + String line; + while ((line = reader.readLine()) != null) { + if (line.startsWith(LINUX_ID_PREFIX)) { + String id = normalizeOsReleaseVariableValue(line.substring(LINUX_ID_PREFIX.length())); + addClassifier(allowedClassifiers, availableClassifiers, id); + } else if (line.startsWith(LINUX_ID_LIKE_PREFIX)) { + line = normalizeOsReleaseVariableValue(line.substring(LINUX_ID_LIKE_PREFIX.length())); + addClassifier(allowedClassifiers, availableClassifiers, line.split("[ ]+")); + } + } + } catch (IOException ignored) { + // Ignore + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException ignored) { + // Ignore + } + } + } + // specification states we should only fall back if /etc/os-release does not exist + break; + } + } + LINUX_OS_CLASSIFIERS = Collections.unmodifiableSet(availableClassifiers); } public static boolean hasDirectBufferNoCleanerConstructor() { @@ -1274,6 +1332,30 @@ public final class PlatformDependent { return NORMALIZED_OS; } + public static Set normalizedLinuxClassifiers() { + return LINUX_OS_CLASSIFIERS; + } + + /** + * Adds only those classifier strings to dest which are present in allowed. + * + * @param allowed allowed classifiers + * @param dest destination set + * @param maybeClassifiers potential classifiers to add + */ + private static void addClassifier(Set allowed, Set dest, String... maybeClassifiers) { + for (String id : maybeClassifiers) { + if (allowed.contains(id)) { + dest.add(id); + } + } + } + + private static String normalizeOsReleaseVariableValue(String value) { + // Variable assignment values may be enclosed in double or single quotes. + return value.trim().replaceAll("[\"']", ""); + } + private static String normalize(String value) { return value.toLowerCase(Locale.US).replaceAll("[^a-z0-9]+", ""); } diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java b/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java index 3d40483807..8dbca2b138 100644 --- a/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java +++ b/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java @@ -552,15 +552,25 @@ public final class OpenSsl { String os = PlatformDependent.normalizedOs(); String arch = PlatformDependent.normalizedArch(); - Set libNames = new LinkedHashSet(4); + Set libNames = new LinkedHashSet(5); String staticLibName = "netty_tcnative"; // First, try loading the platform-specific library. Platform-specific // libraries will be available if using a tcnative uber jar. - libNames.add(staticLibName + "_" + os + '_' + arch); if ("linux".equalsIgnoreCase(os)) { - // Fedora SSL lib so naming (libssl.so.10 vs libssl.so.1.0.0).. + Set classifiers = PlatformDependent.normalizedLinuxClassifiers(); + for (String classifier : classifiers) { + libNames.add(staticLibName + "_" + os + '_' + arch + "_" + classifier); + } + // generic arch-dependent library + libNames.add(staticLibName + "_" + os + '_' + arch); + + // Fedora SSL lib so naming (libssl.so.10 vs libssl.so.1.0.0). + // note: should already be included from the classifiers but if not, we use this as an + // additional fallback option here libNames.add(staticLibName + "_" + os + '_' + arch + "_fedora"); + } else { + libNames.add(staticLibName + "_" + os + '_' + arch); } libNames.add(staticLibName + "_" + arch); libNames.add(staticLibName); diff --git a/pom.xml b/pom.xml index fcd1e39422..d82943e7c0 100644 --- a/pom.xml +++ b/pom.xml @@ -296,8 +296,9 @@ -D_ - fedora 1.6.2 + + fedora,suse,arch netty-tcnative 2.0.25.Final ${os.detected.classifier}