From c3d4277ae61d8fd5b0f954ad24a946dc9f1fc678 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 15 Mar 2024 13:52:34 +0100 Subject: [PATCH] More error-robust kernel version parsing (#4496) * should resolve https://github.com/GeyserMC/Geyser/issues/4492 * Use regex to parse version * yeet debug * Only log the throwable message --- .../geyser/network/netty/Bootstraps.java | 50 ++++++++----------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java b/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java index 9ffc45650..9f889a6e7 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/Bootstraps.java @@ -31,18 +31,18 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.epoll.Native; import io.netty.channel.unix.UnixChannelOption; import lombok.experimental.UtilityClass; +import org.geysermc.geyser.GeyserImpl; -import java.util.Optional; import java.util.concurrent.CompletableFuture; +import java.util.regex.Matcher; +import java.util.regex.Pattern; -@SuppressWarnings("OptionalUsedAsFieldOrParameterType") @UtilityClass public final class Bootstraps { - private static final Optional KERNEL_VERSION; // The REUSEPORT_AVAILABLE socket option is available starting from kernel version 3.9. // This option allows multiple sockets to listen on the same IP address and port without conflict. - private static final int[] REUSEPORT_VERSION = new int[]{3, 9, 0}; + private static final int[] REUSEPORT_VERSION = new int[]{3, 9}; private static final boolean REUSEPORT_AVAILABLE; static { @@ -50,24 +50,16 @@ public final class Bootstraps { try { kernelVersion = Native.KERNEL_VERSION; } catch (Throwable e) { + GeyserImpl.getInstance().getLogger().debug("Could not determine kernel version! " + e.getMessage()); kernelVersion = null; } - if (kernelVersion != null && kernelVersion.contains("-")) { - int index = kernelVersion.indexOf('-'); - if (index > -1) { - kernelVersion = kernelVersion.substring(0, index); - } - int[] kernelVer = fromString(kernelVersion); - KERNEL_VERSION = Optional.of(kernelVer); - REUSEPORT_AVAILABLE = checkVersion(kernelVer, 0); - } else { - KERNEL_VERSION = Optional.empty(); - REUSEPORT_AVAILABLE = false; - } - } - public static Optional getKernelVersion() { - return KERNEL_VERSION; + if (kernelVersion == null) { + REUSEPORT_AVAILABLE = false; + } else { + int[] kernelVer = fromString(kernelVersion); + REUSEPORT_AVAILABLE = checkVersion(kernelVer, 0); + } } public static boolean isReusePortAvailable() { @@ -81,17 +73,19 @@ public final class Bootstraps { } } - private static int[] fromString(String ver) { - String[] parts = ver.split("\\."); - if (parts.length < 2) { - throw new IllegalArgumentException("At least 2 version numbers required"); + private static int[] fromString(String input) { + // Match only beginning of string for at least two digits separated by dot + Pattern pattern = Pattern.compile("^(\\d+)\\.(\\d+)"); + Matcher matcher = pattern.matcher(input); + + int[] version = {0, 0}; + + if (matcher.find()) { + version[0] = Integer.parseInt(matcher.group(1)); + version[1] = Integer.parseInt(matcher.group(2)); } - return new int[]{ - Integer.parseInt(parts[0]), - Integer.parseInt(parts[1]), - parts.length == 2 ? 0 : Integer.parseInt(parts[2]) - }; + return version; } private static boolean checkVersion(int[] ver, int i) {