diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 187f5e39c..7a0f5a7d0 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" spotbugs-annotations = "com.github.spotbugs:spotbugs-annotations:4.7.3" 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 ddd40b4a7..088aef107 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/network/ConnectionManager.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/network/ConnectionManager.java @@ -125,8 +125,8 @@ public final class ConnectionManager { if (address instanceof InetSocketAddress) { bootstrap.childOption(ChannelOption.TCP_NODELAY, true) .childOption(ChannelOption.IP_TOS, 0x18); - if (transportType == TransportType.EPOLL && server.getConfiguration().useTcpFastOpen()) { - bootstrap.option(EpollChannelOption.TCP_FASTOPEN, 3); + if (server.getConfiguration().useTcpFastOpen()) { + bootstrap.option(ChannelOption.TCP_FASTOPEN, 3); } } @@ -190,8 +190,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 bef9f0377..0608fcf1f 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/network/TransportType.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/network/TransportType.java @@ -29,6 +29,13 @@ import io.netty.channel.epoll.EpollEventLoopGroup; import io.netty.channel.epoll.EpollServerDomainSocketChannel; 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.KQueueDomainSocketChannel; +import io.netty.channel.kqueue.KQueueEventLoopGroup; +import io.netty.channel.kqueue.KQueueServerDomainSocketChannel; +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; @@ -58,7 +65,13 @@ public enum TransportType { EpollDatagramChannel::new, EpollServerDomainSocketChannel::new, EpollDomainSocketChannel::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, + KQueueServerDomainSocketChannel::new, + KQueueDomainSocketChannel::new, + (name, type) -> new KQueueEventLoopGroup(0, createThreadFactory(name, type))); final String name; final ChannelFactory serverSocketChannelFactory; @@ -145,6 +158,10 @@ public enum TransportType { return EPOLL; } + if (KQueue.isAvailable()) { + return KQUEUE; + } + return NIO; }