diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4fdfa07a0..df4fb54db 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -46,6 +46,7 @@ netty-codec-haproxy = { module = "io.netty:netty-codec-haproxy", version.ref = " netty-codec-http = { module = "io.netty:netty-codec-http", version.ref = "netty" } netty-handler = { module = "io.netty:netty-handler", version.ref = "netty" } netty-transport-native-epoll = { module = "io.netty:netty-transport-native-epoll", version.ref = "netty" } +netty-transport-native-kqueue = { module = "io.netty:netty-transport-native-kqueue", version.ref = "netty" } nightconfig = "com.electronwill.night-config:toml:3.6.6" slf4j = "org.slf4j:slf4j-api:2.0.7" snakeyaml = "org.yaml:snakeyaml:1.33" diff --git a/proxy/build.gradle.kts b/proxy/build.gradle.kts index 322888a27..fd7042ecd 100644 --- a/proxy/build.gradle.kts +++ b/proxy/build.gradle.kts @@ -101,6 +101,9 @@ dependencies { implementation(libs.netty.transport.native.epoll) implementation(variantOf(libs.netty.transport.native.epoll) { classifier("linux-x86_64") }) implementation(variantOf(libs.netty.transport.native.epoll) { classifier("linux-aarch_64") }) + implementation(libs.netty.transport.native.kqueue) + implementation(variantOf(libs.netty.transport.native.kqueue) { classifier("osx-x86_64") }) + implementation(variantOf(libs.netty.transport.native.kqueue) { classifier("osx-aarch_64") }) implementation(libs.jopt) implementation(libs.terminalconsoleappender) diff --git a/proxy/src/main/java/com/velocitypowered/proxy/network/ConnectionManager.java b/proxy/src/main/java/com/velocitypowered/proxy/network/ConnectionManager.java index bf596e8e3..6175f82e2 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/network/ConnectionManager.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/network/ConnectionManager.java @@ -35,7 +35,6 @@ import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.WriteBufferWaterMark; -import io.netty.channel.epoll.EpollChannelOption; import io.netty.util.concurrent.GlobalEventExecutor; import java.net.InetSocketAddress; import java.util.HashMap; @@ -123,8 +122,8 @@ public final class ConnectionManager { .childOption(ChannelOption.IP_TOS, 0x18) .localAddress(address); - if (transportType == TransportType.EPOLL && server.getConfiguration().useTcpFastOpen()) { - bootstrap.option(EpollChannelOption.TCP_FASTOPEN, 3); + if (server.getConfiguration().useTcpFastOpen()) { + bootstrap.option(ChannelOption.TCP_FASTOPEN, 3); } bootstrap.bind() @@ -186,8 +185,8 @@ public final class ConnectionManager { this.server.getConfiguration().getConnectTimeout()) .group(group == null ? this.workerGroup : group) .resolver(this.resolver.asGroup()); - if (transportType == TransportType.EPOLL && server.getConfiguration().useTcpFastOpen()) { - bootstrap.option(EpollChannelOption.TCP_FASTOPEN_CONNECT, true); + if (server.getConfiguration().useTcpFastOpen()) { + bootstrap.option(ChannelOption.TCP_FASTOPEN_CONNECT, true); } return bootstrap; } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/network/TransportType.java b/proxy/src/main/java/com/velocitypowered/proxy/network/TransportType.java index a7c65fef5..6cbdfd8c5 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/network/TransportType.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/network/TransportType.java @@ -25,6 +25,11 @@ import io.netty.channel.epoll.EpollDatagramChannel; import io.netty.channel.epoll.EpollEventLoopGroup; import io.netty.channel.epoll.EpollServerSocketChannel; import io.netty.channel.epoll.EpollSocketChannel; +import io.netty.channel.kqueue.KQueue; +import io.netty.channel.kqueue.KQueueDatagramChannel; +import io.netty.channel.kqueue.KQueueEventLoopGroup; +import io.netty.channel.kqueue.KQueueServerSocketChannel; +import io.netty.channel.kqueue.KQueueSocketChannel; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.DatagramChannel; import io.netty.channel.socket.ServerSocketChannel; @@ -46,7 +51,11 @@ public enum TransportType { EPOLL("epoll", EpollServerSocketChannel::new, EpollSocketChannel::new, EpollDatagramChannel::new, - (name, type) -> new EpollEventLoopGroup(0, createThreadFactory(name, type))); + (name, type) -> new EpollEventLoopGroup(0, createThreadFactory(name, type))), + KQUEUE("kqueue", KQueueServerSocketChannel::new, + KQueueSocketChannel::new, + KQueueDatagramChannel::new, + (name, type) -> new KQueueEventLoopGroup(0, createThreadFactory(name, type))); final String name; final ChannelFactory serverSocketChannelFactory; @@ -93,6 +102,10 @@ public enum TransportType { return EPOLL; } + if (KQueue.isAvailable()) { + return KQUEUE; + } + return NIO; }