diff --git a/.github/workflows/ci-matrix-5.x.yml b/.github/workflows/ci-matrix-5.x.yml
index 51dc69c5458..43d28fd0ca4 100644
--- a/.github/workflows/ci-matrix-5.x.yml
+++ b/.github/workflows/ci-matrix-5.x.yml
@@ -21,6 +21,9 @@ jobs:
- os: ubuntu-latest
jdk: 11
profile: '-PNativeEpoll+DomainSockets'
+ - os: ubuntu-latest
+ jdk: 11
+ profile: '-PNativeIoUring+DomainSockets'
- os: ubuntu-latest
jdk: 25
- os: windows-2022
diff --git a/vertx-core/pom.xml b/vertx-core/pom.xml
index d3b5c8d2553..b53cc5a66cf 100644
--- a/vertx-core/pom.xml
+++ b/vertx-core/pom.xml
@@ -780,6 +780,29 @@
+
+ NativeIoUring+DomainSockets
+
+ io_uring
+ true
+ false
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+
+ io.vertx.tests.net.NetBandwidthLimitingTest,io.vertx.tests.net.NetTest#testListenDomainSocketAddressNative,HttpDomainSocketTest#testListenDomainSocketAddressNative,
+
+
+
+
+
+
+
NativeKQueue
diff --git a/vertx-core/src/main/java/io/vertx/core/impl/transports/IoUringTransport.java b/vertx-core/src/main/java/io/vertx/core/impl/transports/IoUringTransport.java
index b8291869f2e..a537af6ed5d 100644
--- a/vertx-core/src/main/java/io/vertx/core/impl/transports/IoUringTransport.java
+++ b/vertx-core/src/main/java/io/vertx/core/impl/transports/IoUringTransport.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2024 Contributors to the Eclipse Foundation
+ * Copyright (c) 2011-2026 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
@@ -12,7 +12,10 @@
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
-import io.netty.channel.*;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFactory;
+import io.netty.channel.IoHandlerFactory;
+import io.netty.channel.ServerChannel;
import io.netty.channel.socket.DatagramChannel;
import io.netty.channel.socket.InternetProtocolFamily;
import io.netty.channel.unix.DomainSocketAddress;
@@ -57,7 +60,7 @@ public IoUringTransport() {
@Override
public boolean supportsDomainSockets() {
- return false;
+ return true;
}
@Override
@@ -68,7 +71,7 @@ public boolean supportFileRegion() {
@Override
public SocketAddress convert(io.vertx.core.net.SocketAddress address) {
if (address.isDomainSocket()) {
- throw new IllegalArgumentException("Domain socket not supported by IOUring transport");
+ return new DomainSocketAddress(address.path());
}
return Transport.super.convert(address);
}
@@ -109,7 +112,7 @@ public ChannelFactory extends DatagramChannel> datagramChannelFactory() {
@Override
public ChannelFactory extends Channel> channelFactory(boolean domainSocket) {
if (domainSocket) {
- throw new IllegalArgumentException();
+ return IoUringDomainSocketChannel::new;
}
return IoUringSocketChannel::new;
}
@@ -117,7 +120,7 @@ public ChannelFactory extends Channel> channelFactory(boolean domainSocket) {
@Override
public ChannelFactory extends ServerChannel> serverChannelFactory(boolean domainSocket) {
if (domainSocket) {
- throw new IllegalArgumentException();
+ return IoUringServerDomainSocketChannel::new;
}
return IoUringServerSocketChannel::new;
}
@@ -131,7 +134,9 @@ public void configure(DatagramChannel channel, DatagramSocketOptions options) {
@Override
public void configure(TcpConfig options, boolean domainSocket, ServerBootstrap bootstrap) {
if (domainSocket) {
- throw new IllegalArgumentException();
+ // Domain sockets don't support TCP-specific options
+ Transport.super.configure(options, domainSocket, bootstrap);
+ return;
}
bootstrap.option(IoUringChannelOption.SO_REUSEPORT, options.isReusePort());
if (options.isTcpFastOpen()) {
@@ -140,13 +145,15 @@ public void configure(TcpConfig options, boolean domainSocket, ServerBootstrap b
bootstrap.childOption(IoUringChannelOption.TCP_USER_TIMEOUT, options.getTcpUserTimeout());
bootstrap.childOption(IoUringChannelOption.TCP_QUICKACK, options.isTcpQuickAck());
bootstrap.childOption(IoUringChannelOption.TCP_CORK, options.isTcpCork());
- Transport.super.configure(options, false, bootstrap);
+ Transport.super.configure(options, domainSocket, bootstrap);
}
@Override
public void configure(TcpConfig options, boolean domainSocket, Bootstrap bootstrap) {
if (domainSocket) {
- throw new IllegalArgumentException();
+ // Domain sockets don't support TCP-specific options
+ Transport.super.configure(options, domainSocket, bootstrap);
+ return;
}
if (options.isTcpFastOpen()) {
bootstrap.option(IoUringChannelOption.TCP_FASTOPEN_CONNECT, options.isTcpFastOpen());
@@ -154,6 +161,6 @@ public void configure(TcpConfig options, boolean domainSocket, Bootstrap bootstr
bootstrap.option(IoUringChannelOption.TCP_USER_TIMEOUT, options.getTcpUserTimeout());
bootstrap.option(IoUringChannelOption.TCP_QUICKACK, options.isTcpQuickAck());
bootstrap.option(IoUringChannelOption.TCP_CORK, options.isTcpCork());
- Transport.super.configure(options, false, bootstrap);
+ Transport.super.configure(options, domainSocket, bootstrap);
}
}
diff --git a/vertx-core/src/test/java/io/vertx/tests/net/NetBandwidthLimitingTest.java b/vertx-core/src/test/java/io/vertx/tests/net/NetBandwidthLimitingTest.java
index bdd33492eae..fd6c5b08059 100644
--- a/vertx-core/src/test/java/io/vertx/tests/net/NetBandwidthLimitingTest.java
+++ b/vertx-core/src/test/java/io/vertx/tests/net/NetBandwidthLimitingTest.java
@@ -11,6 +11,19 @@
package io.vertx.tests.net;
+import io.vertx.core.AbstractVerticle;
+import io.vertx.core.DeploymentOptions;
+import io.vertx.core.Future;
+import io.vertx.core.Promise;
+import io.vertx.core.buffer.Buffer;
+import io.vertx.core.net.*;
+import io.vertx.test.core.TestUtils;
+import io.vertx.test.core.VertxTestBase;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
@@ -23,19 +36,6 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
-import io.vertx.core.net.*;
-import io.vertx.core.transport.Transport;
-import org.junit.*;
-import org.junit.rules.TemporaryFolder;
-
-import io.vertx.core.AbstractVerticle;
-import io.vertx.core.DeploymentOptions;
-import io.vertx.core.Future;
-import io.vertx.core.Promise;
-import io.vertx.core.buffer.Buffer;
-import io.vertx.test.core.TestUtils;
-import io.vertx.test.core.VertxTestBase;
-
import static io.vertx.core.net.NetServerOptions.DEFAULT_PORT;
public class NetBandwidthLimitingTest extends VertxTestBase {
@@ -84,7 +84,6 @@ protected void tearDown() throws Exception {
@Test
public void sendBufferThrottled() {
- Assume.assumeFalse(TRANSPORT == Transport.IO_URING);
long startTime = System.nanoTime();
Buffer expected = TestUtils.randomBuffer(64 * 1024 * 4);
@@ -117,7 +116,6 @@ public void sendBufferThrottled() {
@Test
public void sendFileIsThrottled() throws Exception {
- Assume.assumeFalse(TRANSPORT == Transport.IO_URING);
long startTime = System.nanoTime();
File fDir = testFolder.newFolder();
@@ -153,7 +151,6 @@ public void sendFileIsThrottled() throws Exception {
@Test
public void dataUploadIsThrottled() {
- Assume.assumeFalse(TRANSPORT == Transport.IO_URING);
long startTime = System.nanoTime();
Buffer expected = TestUtils.randomBuffer(64 * 1024 * 4);
@@ -185,7 +182,6 @@ public void dataUploadIsThrottled() {
@Test
public void fileUploadIsThrottled() throws Exception {
- Assume.assumeFalse(TRANSPORT == Transport.IO_URING);
long startTime = System.nanoTime();
File fDir = testFolder.newFolder();
@@ -220,7 +216,6 @@ public void fileUploadIsThrottled() throws Exception {
@Test
public void testSendBufferIsTrafficShapedWithSharedServers() throws Exception {
- Assume.assumeFalse(TRANSPORT == Transport.IO_URING);
Buffer expected = TestUtils.randomBuffer(64 * 1024 * 4);
int numEventLoops = 4; // We start a shared TCP server with 4 event-loops
@@ -264,8 +259,6 @@ public void start(Promise startPromise) {
@Test
public void testDynamicInboundRateUpdate() {
- Assume.assumeFalse(TRANSPORT == Transport.IO_URING);
-
Buffer expected = TestUtils.randomBuffer(64 * 1024 * 4);
NetServer server = netServer();
@@ -299,7 +292,6 @@ public void testDynamicInboundRateUpdate() {
@Test
public void testDynamicOutboundRateUpdate() {
- Assume.assumeFalse(TRANSPORT == Transport.IO_URING);
long startTime = System.nanoTime();
Buffer expected = TestUtils.randomBuffer(64 * 1024 * 4);
@@ -338,7 +330,6 @@ public void testDynamicOutboundRateUpdate() {
@Test(expected = IllegalStateException.class)
public void testRateUpdateWhenServerStartedWithoutTrafficShaping() throws Exception {
- Assume.assumeFalse(TRANSPORT == Transport.IO_URING);
NetServerOptions options = new NetServerOptions().setHost(DEFAULT_HOST).setPort(DEFAULT_PORT);
NetServer testServer = netServer(options);