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
This commit is contained in:
chris 2024-03-15 13:52:34 +01:00 committed by GitHub
parent c91ee53788
commit c3d4277ae6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 22 additions and 28 deletions

View File

@ -31,18 +31,18 @@ import io.netty.channel.ChannelFuture;
import io.netty.channel.epoll.Native; import io.netty.channel.epoll.Native;
import io.netty.channel.unix.UnixChannelOption; import io.netty.channel.unix.UnixChannelOption;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import org.geysermc.geyser.GeyserImpl;
import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@UtilityClass @UtilityClass
public final class Bootstraps { public final class Bootstraps {
private static final Optional<int[]> KERNEL_VERSION;
// The REUSEPORT_AVAILABLE socket option is available starting from kernel version 3.9. // 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. // 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; private static final boolean REUSEPORT_AVAILABLE;
static { static {
@ -50,24 +50,16 @@ public final class Bootstraps {
try { try {
kernelVersion = Native.KERNEL_VERSION; kernelVersion = Native.KERNEL_VERSION;
} catch (Throwable e) { } catch (Throwable e) {
GeyserImpl.getInstance().getLogger().debug("Could not determine kernel version! " + e.getMessage());
kernelVersion = null; 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<int[]> getKernelVersion() { if (kernelVersion == null) {
return KERNEL_VERSION; REUSEPORT_AVAILABLE = false;
} else {
int[] kernelVer = fromString(kernelVersion);
REUSEPORT_AVAILABLE = checkVersion(kernelVer, 0);
}
} }
public static boolean isReusePortAvailable() { public static boolean isReusePortAvailable() {
@ -81,17 +73,19 @@ public final class Bootstraps {
} }
} }
private static int[] fromString(String ver) { private static int[] fromString(String input) {
String[] parts = ver.split("\\."); // Match only beginning of string for at least two digits separated by dot
if (parts.length < 2) { Pattern pattern = Pattern.compile("^(\\d+)\\.(\\d+)");
throw new IllegalArgumentException("At least 2 version numbers required"); 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[]{ return version;
Integer.parseInt(parts[0]),
Integer.parseInt(parts[1]),
parts.length == 2 ? 0 : Integer.parseInt(parts[2])
};
} }
private static boolean checkVersion(int[] ver, int i) { private static boolean checkVersion(int[] ver, int i) {