Skip to content

Commit b995822

Browse files
committed
Quic API and implementation - this is a work in progress.
1 parent 408a6de commit b995822

27 files changed

+1886
-4
lines changed

vertx-core/pom.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,16 @@
9898
<artifactId>netty-transport-classes-kqueue</artifactId>
9999
<optional>true</optional>
100100
</dependency>
101+
<dependency>
102+
<groupId>io.netty</groupId>
103+
<artifactId>netty-codec-classes-quic</artifactId>
104+
<optional>true</optional>
105+
</dependency>
106+
<dependency>
107+
<groupId>io.netty</groupId>
108+
<artifactId>netty-codec-native-quic</artifactId>
109+
<optional>true</optional>
110+
</dependency>
101111

102112
<!-- Jackson -->
103113
<dependency>
@@ -989,6 +999,12 @@
989999
<classifier>osx-aarch_64</classifier>
9901000
<scope>test</scope>
9911001
</dependency>
1002+
<dependency>
1003+
<groupId>io.netty</groupId>
1004+
<artifactId>netty-codec-native-quic</artifactId>
1005+
<classifier>osx-aarch_64</classifier>
1006+
<scope>test</scope>
1007+
</dependency>
9921008
</dependencies>
9931009
</profile>
9941010

vertx-core/src/main/java/io/vertx/core/internal/net/SslChannelProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ private SslHandler createServerSslHandler(boolean useAlpn, long sslHandshakeTime
8383

8484
private SniHandler createSniHandler(boolean useAlpn, long sslHandshakeTimeout, TimeUnit sslHandshakeTimeoutUnit, HostAndPort remoteAddress) {
8585
Executor delegatedTaskExec = sslContextProvider.useWorkerPool() ? workerPool : ImmediateExecutor.INSTANCE;
86-
return new VertxSniHandler(sslContextProvider.serverNameMapping(delegatedTaskExec, useAlpn), sslHandshakeTimeoutUnit.toMillis(sslHandshakeTimeout), delegatedTaskExec, remoteAddress);
86+
return new VertxSniHandler(sslContextProvider.serverNameAsyncMapping(delegatedTaskExec, useAlpn), sslHandshakeTimeoutUnit.toMillis(sslHandshakeTimeout), delegatedTaskExec, remoteAddress);
8787
}
8888

8989
}

vertx-core/src/main/java/io/vertx/core/internal/tls/SslContextProvider.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import io.netty.handler.ssl.SniHandler;
1414
import io.netty.handler.ssl.SslContext;
1515
import io.netty.util.AsyncMapping;
16+
import io.netty.util.Mapping;
1617
import io.vertx.core.VertxException;
1718
import io.vertx.core.http.ClientAuth;
1819
import io.vertx.core.spi.tls.SslContextFactory;
@@ -147,12 +148,28 @@ public SslContext sslServerContext(boolean useAlpn) {
147148
}
148149
}
149150

151+
/**
152+
*
153+
* @param useAlpn
154+
* @return
155+
*/
156+
public Mapping<? super String, ? extends SslContext> serverNameMapping(boolean useAlpn) {
157+
return (Mapping<String, SslContext>) serverName -> {
158+
try {
159+
return sslContext(serverName, useAlpn, true);
160+
} catch (Exception e) {
161+
// Log this
162+
return null;
163+
}
164+
};
165+
}
166+
150167
/**
151168
* Server name {@link AsyncMapping} for {@link SniHandler}, mapping happens on a Vert.x worker thread.
152169
*
153170
* @return the {@link AsyncMapping}
154171
*/
155-
public AsyncMapping<? super String, ? extends SslContext> serverNameMapping(Executor workerPool, boolean useAlpn) {
172+
public AsyncMapping<? super String, ? extends SslContext> serverNameAsyncMapping(Executor workerPool, boolean useAlpn) {
156173
return (AsyncMapping<String, SslContext>) (serverName, promise) -> {
157174
workerPool.execute(() -> {
158175
SslContext sslContext;

vertx-core/src/main/java/io/vertx/core/net/TcpOptions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ void init() {
5454
}
5555

5656
@Override
57-
TcpOptions copy() {
57+
protected TcpOptions copy() {
5858
return new TcpOptions(this);
5959
}
6060

vertx-core/src/main/java/io/vertx/core/net/TransportOptions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
*/
1616
public abstract class TransportOptions {
1717

18-
abstract TransportOptions copy();
18+
protected abstract TransportOptions copy();
1919

2020
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2011-2025 Contributors to the Eclipse Foundation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
8+
*
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10+
*/
11+
package io.vertx.core.quic;
12+
13+
import io.vertx.core.buffer.Buffer;
14+
15+
/**
16+
* @author <a href="mailto:[email protected]">Julien Viet</a>
17+
*/
18+
public class ConnectionClose {
19+
20+
private int error;
21+
private Buffer reason;
22+
23+
public int getError() {
24+
return error;
25+
}
26+
27+
public ConnectionClose setError(int error) {
28+
this.error = error;
29+
return this;
30+
}
31+
32+
public Buffer getReason() {
33+
return reason;
34+
}
35+
36+
public ConnectionClose setReason(Buffer reason) {
37+
this.reason = reason;
38+
return this;
39+
}
40+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2011-2025 Contributors to the Eclipse Foundation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
8+
*
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10+
*/
11+
package io.vertx.core.quic;
12+
13+
import io.vertx.core.Future;
14+
import io.vertx.core.Vertx;
15+
import io.vertx.core.internal.VertxInternal;
16+
import io.vertx.core.net.SocketAddress;
17+
import io.vertx.core.quic.impl.QuicClientImpl;
18+
import io.vertx.core.quic.impl.QuicServerImpl;
19+
20+
/**
21+
* @author <a href="mailto:[email protected]">Julien Viet</a>
22+
*/
23+
public interface QuicClient extends QuicEndpoint {
24+
25+
static QuicClient create(Vertx vertx, QuicClientOptions options) {
26+
return QuicClientImpl.create((VertxInternal) vertx, options);
27+
}
28+
29+
Future<QuicConnection> connect(SocketAddress remotePeer);
30+
31+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) 2011-2025 Contributors to the Eclipse Foundation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
8+
*
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10+
*/
11+
package io.vertx.core.quic;
12+
13+
import io.vertx.core.net.ClientSSLOptions;
14+
15+
/**
16+
* @author <a href="mailto:[email protected]">Julien Viet</a>
17+
*/
18+
public class QuicClientOptions extends QuicEndpointOptions {
19+
20+
public QuicClientOptions() {
21+
}
22+
23+
public QuicClientOptions(QuicClientOptions other) {
24+
super(other);
25+
}
26+
27+
@Override
28+
public ClientSSLOptions getSslOptions() {
29+
return (ClientSSLOptions) super.getSslOptions();
30+
}
31+
32+
@Override
33+
protected ClientSSLOptions getOrCreateSSLOptions() {
34+
return new ClientSSLOptions();
35+
}
36+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (c) 2011-2025 Contributors to the Eclipse Foundation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
8+
*
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10+
*/
11+
package io.vertx.core.quic;
12+
13+
import io.vertx.codegen.annotations.GenIgnore;
14+
import io.vertx.core.Future;
15+
import io.vertx.core.Handler;
16+
17+
import javax.net.ssl.SSLSession;
18+
19+
/**
20+
* @author <a href="mailto:[email protected]">Julien Viet</a>
21+
*/
22+
public interface QuicConnection {
23+
24+
QuicConnection handler(Handler<QuicStream> handler);
25+
26+
QuicConnection closeHandler(Handler<Void> handler);
27+
28+
Future<QuicStream> createStream();
29+
30+
Future<Void> close();
31+
32+
Future<Void> close(ConnectionClose payload);
33+
34+
/**
35+
* @return the application-level protocol negotiated during the TLS handshake
36+
*/
37+
String applicationLayerProtocol();
38+
39+
/**
40+
* @return SSLSession associated with the underlying socket. Returns null if connection is
41+
* not SSL.
42+
* @see javax.net.ssl.SSLSession
43+
*/
44+
@GenIgnore(GenIgnore.PERMITTED_TYPE)
45+
SSLSession sslSession();
46+
47+
ConnectionClose closePayload();
48+
49+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) 2011-2025 Contributors to the Eclipse Foundation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
8+
*
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10+
*/
11+
package io.vertx.core.quic;
12+
13+
import io.vertx.core.Future;
14+
import io.vertx.core.net.SocketAddress;
15+
16+
/**
17+
* @author <a href="mailto:[email protected]">Julien Viet</a>
18+
*/
19+
public interface QuicEndpoint {
20+
21+
Future<Void> bind(SocketAddress address);
22+
23+
Future<Void> close();
24+
25+
}

0 commit comments

Comments
 (0)