From 95504d9b7778db3f63dd17cd10d574d9c63c16da Mon Sep 17 00:00:00 2001 From: Laivy Date: Wed, 26 Nov 2025 20:16:16 -0300 Subject: [PATCH 01/17] done changes --- .idea/.gitignore | 3 + .idea/.name | 1 + .idea/compiler.xml | 15 +++ .idea/encodings.xml | 7 + .idea/gradle.xml | 24 ++++ .idea/inspectionProfiles/Project_Default.xml | 19 +++ .idea/jarRepositories.xml | 20 +++ .idea/misc.xml | 16 +++ .idea/uiDesigner.xml | 124 ++++++++++++++++++ .idea/vcs.xml | 6 + .../java/tech/kwik/cli/InteractiveShell.java | 6 +- cli/src/main/java/tech/kwik/cli/KwikCli.java | 17 +-- core/src/main/java/module-info.java | 1 + .../java/tech/kwik/core/QuicConnection.java | 7 + .../tech/kwik/core/QuicSessionTicket.java | 2 +- .../tech/kwik/core/StreamReadListener.java | 23 ++++ .../tech/kwik/core/StreamWriteListener.java | 23 ++++ .../kwik/core/cid/ConnectionIdManager.java | 4 +- .../java/tech/kwik/core/crypto/Aes128Gcm.java | 6 +- .../java/tech/kwik/core/crypto/ChaCha20.java | 6 +- .../tech/kwik/core/crypto/CryptoStream.java | 2 +- .../core/impl/QuicClientConnectionImpl.java | 26 +--- .../kwik/core/impl/QuicConnectionImpl.java | 29 +++- .../kwik/core/impl/QuicSessionTicketImpl.java | 2 +- .../java/tech/kwik/core/log/FileLogger.java | 6 +- .../core/packet/ClientRolePacketParser.java | 10 +- .../core/packet/ServerRolePacketParser.java | 6 +- .../kwik/core/packet/ShortHeaderPacket.java | 6 +- .../kwik/core/recovery/RecoveryManager.java | 6 +- .../kwik/core/send/GlobalPacketAssembler.java | 12 +- .../core/send/InitialPacketAssembler.java | 2 +- .../java/tech/kwik/core/send/SenderImpl.java | 6 +- .../kwik/core/server/ServerConnection.java | 4 +- .../impl/InitialPacketMinimumSizeFilter.java | 6 +- .../server/impl/ServerConnectionImpl.java | 27 +--- .../impl/ServerConnectionRegistryImpl.java | 6 +- .../core/server/impl/ServerConnectorImpl.java | 6 +- .../kwik/core/stream/ListenerThreadPool.java | 49 +++++++ .../tech/kwik/core/stream/QuicStreamImpl.java | 9 +- .../kwik/core/stream/ReceiveBufferImpl.java | 40 +++++- .../tech/kwik/core/stream/SendBuffer.java | 66 +++++++--- .../core/stream/StreamInputStreamImpl.java | 2 +- .../tech/kwik/core/stream/StreamManager.java | 6 +- .../core/stream/StreamOutputStreamImpl.java | 12 +- .../java/tech/kwik/core/StatisticsTest.java | 2 +- .../core/cc/CongestionControllerTest.java | 6 +- .../cc/NewRenoCongestionControllerTest.java | 6 +- .../DestinationConnectionIdRegistryTest.java | 2 +- .../core/crypto/ConnectionSecretsTest.java | 2 +- .../kwik/core/crypto/CryptoStreamTest.java | 4 +- .../tech/kwik/core/frame/CryptoFrameTest.java | 2 +- .../core/frame/NewConnectionIdFrameTest.java | 2 +- .../tech/kwik/core/frame/PaddingTest.java | 2 +- .../frame/RetireConnectionIdFrameTest.java | 2 +- .../kwik/core/frame/StopSendingFrameTest.java | 2 +- .../frame/StreamDataBlockedFrameTest.java | 2 +- .../tech/kwik/core/frame/StreamFrameTest.java | 2 +- .../core/frame/StreamsBlockedFrameTest.java | 2 +- .../kwik/core/impl/EncryptionLevelTest.java | 4 +- .../tech/kwik/core/impl/IdleTimerTest.java | 8 +- .../kwik/core/impl/KeepAliveActorTest.java | 6 +- .../impl/PacketMatcherByConnectionId.java | 2 +- .../core/impl/PacketMatcherByFrameClass.java | 2 +- .../impl/PacketMatcherByPacketNumber.java | 2 +- .../java/tech/kwik/core/impl/PaddingTest.java | 4 +- .../java/tech/kwik/core/impl/PnSpaceTest.java | 4 +- .../impl/QuicClientConnectionImplTest.java | 6 +- .../core/impl/QuicSessionTicketImplTest.java | 2 +- .../java/tech/kwik/core/impl/TestUtils.java | 4 +- .../packet/ClientRolePacketParserTest.java | 4 +- .../kwik/core/packet/HandshakePacketTest.java | 6 +- .../core/packet/LongHeaderPacketTest.java | 2 +- .../kwik/core/packet/RetryPacketTest.java | 2 +- .../packet/ServerRolePacketParserTest.java | 8 +- .../core/packet/ShortHeaderPacketTest.java | 6 +- .../packet/VersionNegotiationPacketTest.java | 4 +- .../kwik/core/packet/ZeroRttPacketTest.java | 6 +- .../tech/kwik/core/receive/ReceiverTest.java | 2 +- .../kwik/core/recovery/RecoveryTests.java | 8 +- .../kwik/core/send/AbstractSenderTest.java | 4 +- .../kwik/core/send/PacketAssemblerTest.java | 4 +- .../kwik/core/send/SendRequestQueueTest.java | 8 +- .../impl/ApplicationProtocolRegistryTest.java | 2 +- .../server/impl/ClientAddressFilterTest.java | 4 +- .../impl/ClientInitialScidFilterTest.java | 4 +- .../impl/InitialPacketFilterProxyTest.java | 4 +- .../InitialPacketMinimumSizeFilterTest.java | 4 +- .../server/impl/ServerConnectionImplTest.java | 6 +- .../server/impl/ServerConnectorImplTest.java | 6 +- .../kwik/core/stream/EarlyDataStreamTest.java | 10 +- .../kwik/core/stream/FlowControlTest.java | 8 +- .../kwik/core/stream/QuicStreamImplTest.java | 6 +- .../core/stream/ReceiveBufferImplTest.java | 2 +- .../core/stream/RetransmitBufferTest.java | 2 +- .../kwik/core/stream/StreamManagerTest.java | 20 +-- .../java/tech/kwik/core/test/TestClock.java | 6 +- .../kwik/core/tls/ClientHelloBuilder.java | 4 +- h09/src/main/java/module-info.java | 1 + .../kwik/h09/io/LimitExceededException.java | 21 +-- .../tech/kwik/h09/io/LimitedInputStream.java | 3 +- .../kwik/h09/server/Http09Connection.java | 6 +- .../kwik/h09/server/Http09ConnectionTest.java | 10 +- .../java/tech/kwik/interop/InteropClient.java | 2 +- .../java/tech/kwik/interop/InteropServer.java | 6 +- .../java/tech/kwik/qlog/ConnectionQLog.java | 6 +- .../java/tech/kwik/qlog/QLogFrontEnd.java | 6 +- .../tech/kwik/qlog/event/PacketSentEvent.java | 20 +-- 107 files changed, 602 insertions(+), 389 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/.name create mode 100644 .idea/compiler.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/uiDesigner.xml create mode 100644 .idea/vcs.xml create mode 100644 core/src/main/java/tech/kwik/core/StreamReadListener.java create mode 100644 core/src/main/java/tech/kwik/core/StreamWriteListener.java create mode 100644 core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..26d33521 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 00000000..af541b14 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +kwik \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 00000000..85d78733 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 00000000..aa00ffab --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 00000000..8c30cb87 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,24 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..886b10d7 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,19 @@ + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 00000000..712ab9d9 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..bf80b57a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 00000000..2b63946d --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/cli/src/main/java/tech/kwik/cli/InteractiveShell.java b/cli/src/main/java/tech/kwik/cli/InteractiveShell.java index 4b6bbc77..c76b34fb 100644 --- a/cli/src/main/java/tech/kwik/cli/InteractiveShell.java +++ b/cli/src/main/java/tech/kwik/cli/InteractiveShell.java @@ -42,11 +42,7 @@ import java.nio.file.Path; import java.time.Duration; import java.time.Instant; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; import java.util.stream.Collectors; diff --git a/cli/src/main/java/tech/kwik/cli/KwikCli.java b/cli/src/main/java/tech/kwik/cli/KwikCli.java index 99fc1720..4f1110e6 100644 --- a/cli/src/main/java/tech/kwik/cli/KwikCli.java +++ b/cli/src/main/java/tech/kwik/cli/KwikCli.java @@ -35,18 +35,10 @@ import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.X509ExtendedKeyManager; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; +import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.net.InetSocketAddress; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; +import java.net.*; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; @@ -57,10 +49,7 @@ import java.nio.file.StandardOpenOption; import java.security.*; import java.security.cert.Certificate; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; +import java.security.cert.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.time.Duration; diff --git a/core/src/main/java/module-info.java b/core/src/main/java/module-info.java index 49d09156..afdcbafe 100644 --- a/core/src/main/java/module-info.java +++ b/core/src/main/java/module-info.java @@ -3,6 +3,7 @@ requires at.favre.lib.hkdf; requires io.whitfin.siphash; requires java.management; + requires java.compiler; exports tech.kwik.core; exports tech.kwik.core.concurrent; diff --git a/core/src/main/java/tech/kwik/core/QuicConnection.java b/core/src/main/java/tech/kwik/core/QuicConnection.java index 97b50493..78da08cd 100644 --- a/core/src/main/java/tech/kwik/core/QuicConnection.java +++ b/core/src/main/java/tech/kwik/core/QuicConnection.java @@ -96,12 +96,19 @@ enum QuicVersion { void setPeerInitiatedStreamCallback(Consumer streamConsumer); + ConnectionListener getConnectionListener(); /** * Register a listener that will be called when the connection is established or terminated. * @param connectionListener */ void setConnectionListener(ConnectionListener connectionListener); + StreamReadListener getStreamReadListener(); + void setStreamReadListener(StreamReadListener listener); + + StreamWriteListener getStreamWriteListener(); + void setStreamWriteListener(StreamWriteListener listener); + void close(); /** diff --git a/core/src/main/java/tech/kwik/core/QuicSessionTicket.java b/core/src/main/java/tech/kwik/core/QuicSessionTicket.java index e2e032b4..a2fc03e7 100644 --- a/core/src/main/java/tech/kwik/core/QuicSessionTicket.java +++ b/core/src/main/java/tech/kwik/core/QuicSessionTicket.java @@ -18,9 +18,9 @@ */ package tech.kwik.core; -import tech.kwik.core.impl.TransportParameters; import tech.kwik.agent15.NewSessionTicket; import tech.kwik.agent15.TlsConstants; +import tech.kwik.core.impl.TransportParameters; public interface QuicSessionTicket { diff --git a/core/src/main/java/tech/kwik/core/StreamReadListener.java b/core/src/main/java/tech/kwik/core/StreamReadListener.java new file mode 100644 index 00000000..995c4f28 --- /dev/null +++ b/core/src/main/java/tech/kwik/core/StreamReadListener.java @@ -0,0 +1,23 @@ +/* + * Copyright © 2024, 2025 Peter Doornbosch + * + * This file is part of Kwik, an implementation of the QUIC protocol in Java. + * + * Kwik is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Kwik is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package tech.kwik.core; + +public interface StreamReadListener { + void read(QuicStream stream, long amount); +} diff --git a/core/src/main/java/tech/kwik/core/StreamWriteListener.java b/core/src/main/java/tech/kwik/core/StreamWriteListener.java new file mode 100644 index 00000000..9e324f05 --- /dev/null +++ b/core/src/main/java/tech/kwik/core/StreamWriteListener.java @@ -0,0 +1,23 @@ +/* + * Copyright © 2024, 2025 Peter Doornbosch + * + * This file is part of Kwik, an implementation of the QUIC protocol in Java. + * + * Kwik is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Kwik is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package tech.kwik.core; + +public interface StreamWriteListener { + void write(QuicStream stream, long amount); +} diff --git a/core/src/main/java/tech/kwik/core/cid/ConnectionIdManager.java b/core/src/main/java/tech/kwik/core/cid/ConnectionIdManager.java index 70d4cc64..34e9df5a 100644 --- a/core/src/main/java/tech/kwik/core/cid/ConnectionIdManager.java +++ b/core/src/main/java/tech/kwik/core/cid/ConnectionIdManager.java @@ -34,9 +34,7 @@ import java.util.function.BiConsumer; import java.util.stream.Stream; -import static tech.kwik.core.QuicConstants.TransportErrorCode.CONNECTION_ID_LIMIT_ERROR; -import static tech.kwik.core.QuicConstants.TransportErrorCode.FRAME_ENCODING_ERROR; -import static tech.kwik.core.QuicConstants.TransportErrorCode.PROTOCOL_VIOLATION; +import static tech.kwik.core.QuicConstants.TransportErrorCode.*; import static tech.kwik.core.common.EncryptionLevel.App; /** diff --git a/core/src/main/java/tech/kwik/core/crypto/Aes128Gcm.java b/core/src/main/java/tech/kwik/core/crypto/Aes128Gcm.java index 75542379..11ed2ea1 100644 --- a/core/src/main/java/tech/kwik/core/crypto/Aes128Gcm.java +++ b/core/src/main/java/tech/kwik/core/crypto/Aes128Gcm.java @@ -7,11 +7,7 @@ import tech.kwik.core.impl.Version; import tech.kwik.core.log.Logger; -import javax.crypto.AEADBadTagException; -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; +import javax.crypto.*; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.InvalidAlgorithmParameterException; diff --git a/core/src/main/java/tech/kwik/core/crypto/ChaCha20.java b/core/src/main/java/tech/kwik/core/crypto/ChaCha20.java index 19abbb01..b9feee09 100644 --- a/core/src/main/java/tech/kwik/core/crypto/ChaCha20.java +++ b/core/src/main/java/tech/kwik/core/crypto/ChaCha20.java @@ -25,11 +25,7 @@ import tech.kwik.core.impl.Version; import tech.kwik.core.log.Logger; -import javax.crypto.AEADBadTagException; -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; +import javax.crypto.*; import javax.crypto.spec.ChaCha20ParameterSpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; diff --git a/core/src/main/java/tech/kwik/core/crypto/CryptoStream.java b/core/src/main/java/tech/kwik/core/crypto/CryptoStream.java index fda42204..9dd0b8c2 100644 --- a/core/src/main/java/tech/kwik/core/crypto/CryptoStream.java +++ b/core/src/main/java/tech/kwik/core/crypto/CryptoStream.java @@ -96,7 +96,7 @@ public CryptoStream(VersionHolder quicVersion, EncryptionLevel encryptionLevel, tlsMessageParser = new TlsMessageParser(this::quicExtensionsParser); dataToSend = new ArrayList<>(); maxMessageSize = determineMaxMessageSize(role, encryptionLevel); - receiveBuffer = new ReceiveBufferImpl(); + receiveBuffer = new ReceiveBufferImpl(null); } public CryptoStream(VersionHolder quicVersion, EncryptionLevel encryptionLevel, Role role, Logger log) { diff --git a/core/src/main/java/tech/kwik/core/impl/QuicClientConnectionImpl.java b/core/src/main/java/tech/kwik/core/impl/QuicClientConnectionImpl.java index 98dcf92a..f5d2e812 100644 --- a/core/src/main/java/tech/kwik/core/impl/QuicClientConnectionImpl.java +++ b/core/src/main/java/tech/kwik/core/impl/QuicClientConnectionImpl.java @@ -21,11 +21,7 @@ import tech.kwik.agent15.NewSessionTicket; import tech.kwik.agent15.TlsConstants; import tech.kwik.agent15.TlsProtocolException; -import tech.kwik.agent15.engine.CertificateWithPrivateKey; -import tech.kwik.agent15.engine.ClientMessageSender; -import tech.kwik.agent15.engine.TlsClientEngine; -import tech.kwik.agent15.engine.TlsClientEngineFactory; -import tech.kwik.agent15.engine.TlsStatusEventHandler; +import tech.kwik.agent15.engine.*; import tech.kwik.agent15.extension.ApplicationLayerProtocolNegotiationExtension; import tech.kwik.agent15.extension.EarlyDataExtension; import tech.kwik.agent15.extension.Extension; @@ -55,20 +51,12 @@ import tech.kwik.core.util.Bytes; import tech.kwik.core.util.InetTools; -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509ExtendedKeyManager; -import javax.net.ssl.X509TrustManager; +import javax.net.ssl.*; import java.io.IOException; import java.net.*; import java.nio.ByteBuffer; import java.nio.file.Path; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.UnrecoverableKeyException; +import java.security.*; import java.security.cert.X509Certificate; import java.time.Duration; import java.time.Instant; @@ -82,12 +70,8 @@ import static tech.kwik.agent15.TlsConstants.SignatureScheme.*; import static tech.kwik.core.QuicConstants.TransportErrorCode.*; -import static tech.kwik.core.common.EncryptionLevel.App; -import static tech.kwik.core.common.EncryptionLevel.Handshake; -import static tech.kwik.core.common.EncryptionLevel.Initial; -import static tech.kwik.core.impl.QuicClientConnectionImpl.EarlyDataStatus.Accepted; -import static tech.kwik.core.impl.QuicClientConnectionImpl.EarlyDataStatus.None; -import static tech.kwik.core.impl.QuicClientConnectionImpl.EarlyDataStatus.Requested; +import static tech.kwik.core.common.EncryptionLevel.*; +import static tech.kwik.core.impl.QuicClientConnectionImpl.EarlyDataStatus.*; import static tech.kwik.core.util.Bytes.bytesToHex; diff --git a/core/src/main/java/tech/kwik/core/impl/QuicConnectionImpl.java b/core/src/main/java/tech/kwik/core/impl/QuicConnectionImpl.java index 2bfed17f..cced43c8 100644 --- a/core/src/main/java/tech/kwik/core/impl/QuicConnectionImpl.java +++ b/core/src/main/java/tech/kwik/core/impl/QuicConnectionImpl.java @@ -55,9 +55,7 @@ import static tech.kwik.core.ConnectionTerminatedEvent.CloseReason; import static tech.kwik.core.ConnectionTerminatedEvent.CloseReason.ConnectionLost; import static tech.kwik.core.QuicConstants.TransportErrorCode.*; -import static tech.kwik.core.common.EncryptionLevel.App; -import static tech.kwik.core.common.EncryptionLevel.Handshake; -import static tech.kwik.core.common.EncryptionLevel.Initial; +import static tech.kwik.core.common.EncryptionLevel.*; import static tech.kwik.core.impl.QuicConnectionImpl.ErrorType.APPLICATION_ERROR; import static tech.kwik.core.impl.QuicConnectionImpl.ErrorType.QUIC_LAYER_ERROR; import static tech.kwik.core.send.Sender.NO_RETRANSMIT; @@ -142,6 +140,8 @@ protected enum ErrorType { private volatile ConnectionCloseFrame lastConnectionCloseFrameSent; private final ScheduledExecutorService scheduler; private ConnectionListener connectionListener; + public StreamReadListener readListener; + public StreamWriteListener writeListener; protected final ExecutorService callbackThread; // https://datatracker.ietf.org/doc/html/rfc9221 Datagram Extension @@ -150,7 +150,6 @@ protected enum ErrorType { private volatile Consumer datagramHandler; private volatile ExecutorService datagramHandlerExecutor; - protected QuicConnectionImpl(Version originalVersion, Role role, Path secretsFile, ConnectionConfig settings, String id, Logger log) { this.quicVersion = new VersionHolder(originalVersion); this.role = role; @@ -961,11 +960,33 @@ public QuicVersion getQuicVersion() { return quicVersion.getVersion().toQuicVersion(); } + @Override + public ConnectionListener getConnectionListener() { + return connectionListener; + } @Override public void setConnectionListener(ConnectionListener connectionListener) { this.connectionListener = connectionListener; } + @Override + public StreamReadListener getStreamReadListener() { + return readListener; + } + @Override + public void setStreamReadListener(StreamReadListener listener) { + this.readListener = listener; + } + + @Override + public StreamWriteListener getStreamWriteListener() { + return writeListener; + } + @Override + public void setStreamWriteListener(StreamWriteListener listener) { + this.writeListener = listener; + } + protected abstract boolean usingIPv4(); protected abstract PacketFilter createProcessorChain(); diff --git a/core/src/main/java/tech/kwik/core/impl/QuicSessionTicketImpl.java b/core/src/main/java/tech/kwik/core/impl/QuicSessionTicketImpl.java index 607bad49..8e77e061 100644 --- a/core/src/main/java/tech/kwik/core/impl/QuicSessionTicketImpl.java +++ b/core/src/main/java/tech/kwik/core/impl/QuicSessionTicketImpl.java @@ -18,9 +18,9 @@ */ package tech.kwik.core.impl; -import tech.kwik.core.QuicSessionTicket; import tech.kwik.agent15.NewSessionTicket; import tech.kwik.agent15.TlsConstants; +import tech.kwik.core.QuicSessionTicket; import java.nio.ByteBuffer; diff --git a/core/src/main/java/tech/kwik/core/log/FileLogger.java b/core/src/main/java/tech/kwik/core/log/FileLogger.java index 8941e5e6..10cacee1 100644 --- a/core/src/main/java/tech/kwik/core/log/FileLogger.java +++ b/core/src/main/java/tech/kwik/core/log/FileLogger.java @@ -18,11 +18,7 @@ */ package tech.kwik.core.log; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; +import java.io.*; import java.nio.ByteBuffer; diff --git a/core/src/main/java/tech/kwik/core/packet/ClientRolePacketParser.java b/core/src/main/java/tech/kwik/core/packet/ClientRolePacketParser.java index cee6f5b1..e2298317 100644 --- a/core/src/main/java/tech/kwik/core/packet/ClientRolePacketParser.java +++ b/core/src/main/java/tech/kwik/core/packet/ClientRolePacketParser.java @@ -18,21 +18,19 @@ */ package tech.kwik.core.packet; -import tech.kwik.core.impl.InvalidPacketException; -import tech.kwik.core.impl.Role; -import tech.kwik.core.impl.VersionHolder; import tech.kwik.core.crypto.Aead; import tech.kwik.core.crypto.ConnectionSecrets; import tech.kwik.core.crypto.MissingKeysException; +import tech.kwik.core.impl.InvalidPacketException; +import tech.kwik.core.impl.Role; +import tech.kwik.core.impl.VersionHolder; import tech.kwik.core.log.Logger; import tech.kwik.core.log.NullLogger; import java.nio.ByteBuffer; import java.util.function.BiFunction; -import static tech.kwik.core.common.EncryptionLevel.App; -import static tech.kwik.core.common.EncryptionLevel.Handshake; -import static tech.kwik.core.common.EncryptionLevel.Initial; +import static tech.kwik.core.common.EncryptionLevel.*; /** * Packet parser for endpoint that has client role. diff --git a/core/src/main/java/tech/kwik/core/packet/ServerRolePacketParser.java b/core/src/main/java/tech/kwik/core/packet/ServerRolePacketParser.java index 0e271bc7..ec88ec8b 100644 --- a/core/src/main/java/tech/kwik/core/packet/ServerRolePacketParser.java +++ b/core/src/main/java/tech/kwik/core/packet/ServerRolePacketParser.java @@ -25,11 +25,7 @@ import tech.kwik.core.generic.IntegerTooLargeException; import tech.kwik.core.generic.InvalidIntegerEncodingException; import tech.kwik.core.generic.VariableLengthInteger; -import tech.kwik.core.impl.InvalidPacketException; -import tech.kwik.core.impl.QuicConnectionImpl; -import tech.kwik.core.impl.Role; -import tech.kwik.core.impl.TransportError; -import tech.kwik.core.impl.VersionHolder; +import tech.kwik.core.impl.*; import tech.kwik.core.log.Logger; import java.nio.ByteBuffer; diff --git a/core/src/main/java/tech/kwik/core/packet/ShortHeaderPacket.java b/core/src/main/java/tech/kwik/core/packet/ShortHeaderPacket.java index 641ab94a..5e774f51 100644 --- a/core/src/main/java/tech/kwik/core/packet/ShortHeaderPacket.java +++ b/core/src/main/java/tech/kwik/core/packet/ShortHeaderPacket.java @@ -23,11 +23,7 @@ import tech.kwik.core.common.PnSpace; import tech.kwik.core.crypto.Aead; import tech.kwik.core.frame.QuicFrame; -import tech.kwik.core.impl.DecryptionException; -import tech.kwik.core.impl.InvalidPacketException; -import tech.kwik.core.impl.PacketProcessor; -import tech.kwik.core.impl.TransportError; -import tech.kwik.core.impl.Version; +import tech.kwik.core.impl.*; import tech.kwik.core.log.Logger; import tech.kwik.core.util.Bytes; diff --git a/core/src/main/java/tech/kwik/core/recovery/RecoveryManager.java b/core/src/main/java/tech/kwik/core/recovery/RecoveryManager.java index ca503240..715de8c8 100644 --- a/core/src/main/java/tech/kwik/core/recovery/RecoveryManager.java +++ b/core/src/main/java/tech/kwik/core/recovery/RecoveryManager.java @@ -34,11 +34,7 @@ import tech.kwik.core.packet.QuicPacket; import tech.kwik.core.send.Sender; -import java.time.Clock; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalTime; -import java.time.ZoneId; +import java.time.*; import java.time.format.DateTimeFormatter; import java.util.Collections; import java.util.List; diff --git a/core/src/main/java/tech/kwik/core/send/GlobalPacketAssembler.java b/core/src/main/java/tech/kwik/core/send/GlobalPacketAssembler.java index 97dacad5..8cc85504 100644 --- a/core/src/main/java/tech/kwik/core/send/GlobalPacketAssembler.java +++ b/core/src/main/java/tech/kwik/core/send/GlobalPacketAssembler.java @@ -28,15 +28,9 @@ import tech.kwik.core.impl.VersionHolder; import java.time.Instant; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static tech.kwik.core.common.EncryptionLevel.Handshake; -import static tech.kwik.core.common.EncryptionLevel.Initial; -import static tech.kwik.core.common.EncryptionLevel.ZeroRTT; +import java.util.*; + +import static tech.kwik.core.common.EncryptionLevel.*; /** * Assembles QUIC packets for sending. diff --git a/core/src/main/java/tech/kwik/core/send/InitialPacketAssembler.java b/core/src/main/java/tech/kwik/core/send/InitialPacketAssembler.java index e247326a..27618f88 100644 --- a/core/src/main/java/tech/kwik/core/send/InitialPacketAssembler.java +++ b/core/src/main/java/tech/kwik/core/send/InitialPacketAssembler.java @@ -20,8 +20,8 @@ import tech.kwik.core.ack.AckGenerator; import tech.kwik.core.common.EncryptionLevel; -import tech.kwik.core.impl.VersionHolder; import tech.kwik.core.frame.QuicFrame; +import tech.kwik.core.impl.VersionHolder; import tech.kwik.core.packet.InitialPacket; import tech.kwik.core.packet.QuicPacket; diff --git a/core/src/main/java/tech/kwik/core/send/SenderImpl.java b/core/src/main/java/tech/kwik/core/send/SenderImpl.java index 8c8ef52e..d29ffb4f 100644 --- a/core/src/main/java/tech/kwik/core/send/SenderImpl.java +++ b/core/src/main/java/tech/kwik/core/send/SenderImpl.java @@ -49,11 +49,7 @@ import java.time.Clock; import java.time.Duration; import java.time.Instant; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Function; diff --git a/core/src/main/java/tech/kwik/core/server/ServerConnection.java b/core/src/main/java/tech/kwik/core/server/ServerConnection.java index c37293fb..2e35fdfb 100644 --- a/core/src/main/java/tech/kwik/core/server/ServerConnection.java +++ b/core/src/main/java/tech/kwik/core/server/ServerConnection.java @@ -21,8 +21,8 @@ import tech.kwik.core.QuicConnection; import java.net.InetAddress; +import java.net.InetSocketAddress; public interface ServerConnection extends QuicConnection { - - InetAddress getInitialClientAddress(); + InetSocketAddress getInitialClientAddress(); } diff --git a/core/src/main/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilter.java b/core/src/main/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilter.java index 2108b1b2..04a6eff2 100644 --- a/core/src/main/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilter.java +++ b/core/src/main/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilter.java @@ -21,11 +21,7 @@ import tech.kwik.core.impl.TransportError; import tech.kwik.core.impl.Version; import tech.kwik.core.log.Logger; -import tech.kwik.core.packet.BaseDatagramFilter; -import tech.kwik.core.packet.DatagramFilter; -import tech.kwik.core.packet.InitialPacket; -import tech.kwik.core.packet.LongHeaderPacket; -import tech.kwik.core.packet.PacketMetaData; +import tech.kwik.core.packet.*; import java.nio.ByteBuffer; diff --git a/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionImpl.java b/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionImpl.java index 41d28bbf..16b9f6a5 100644 --- a/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionImpl.java +++ b/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionImpl.java @@ -23,11 +23,7 @@ import tech.kwik.agent15.TlsProtocolException; import tech.kwik.agent15.alert.MissingExtensionAlert; import tech.kwik.agent15.alert.NoApplicationProtocolAlert; -import tech.kwik.agent15.engine.ServerMessageSender; -import tech.kwik.agent15.engine.TlsEngine; -import tech.kwik.agent15.engine.TlsServerEngine; -import tech.kwik.agent15.engine.TlsServerEngineFactory; -import tech.kwik.agent15.engine.TlsStatusEventHandler; +import tech.kwik.agent15.engine.*; import tech.kwik.agent15.extension.ApplicationLayerProtocolNegotiationExtension; import tech.kwik.agent15.extension.Extension; import tech.kwik.agent15.handshake.*; @@ -38,21 +34,13 @@ import tech.kwik.core.common.EncryptionLevel; import tech.kwik.core.common.PnSpace; import tech.kwik.core.crypto.CryptoStream; -import tech.kwik.core.frame.CryptoFrame; -import tech.kwik.core.frame.HandshakeDoneFrame; -import tech.kwik.core.frame.NewTokenFrame; -import tech.kwik.core.frame.QuicFrame; -import tech.kwik.core.frame.RetireConnectionIdFrame; +import tech.kwik.core.frame.*; import tech.kwik.core.impl.*; import tech.kwik.core.log.LogProxy; import tech.kwik.core.log.Logger; import tech.kwik.core.packet.*; import tech.kwik.core.send.SenderImpl; -import tech.kwik.core.server.ApplicationProtocolConnectionFactory; -import tech.kwik.core.server.ApplicationProtocolSettings; -import tech.kwik.core.server.ServerConnection; -import tech.kwik.core.server.ServerConnectionConfig; -import tech.kwik.core.server.ServerConnectionRegistry; +import tech.kwik.core.server.*; import tech.kwik.core.stream.FlowControl; import tech.kwik.core.stream.StreamManager; import tech.kwik.core.tls.QuicTransportParametersExtension; @@ -61,7 +49,6 @@ import java.io.IOException; import java.net.DatagramSocket; -import java.net.InetAddress; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.security.SecureRandom; @@ -73,9 +60,7 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; -import static tech.kwik.core.QuicConstants.TransportErrorCode.INVALID_TOKEN; -import static tech.kwik.core.QuicConstants.TransportErrorCode.PROTOCOL_VIOLATION; -import static tech.kwik.core.QuicConstants.TransportErrorCode.TRANSPORT_PARAMETER_ERROR; +import static tech.kwik.core.QuicConstants.TransportErrorCode.*; import static tech.kwik.core.common.EncryptionLevel.Initial; import static tech.kwik.core.impl.QuicConnectionImpl.Status.Connected; import static tech.kwik.core.impl.QuicConnectionImpl.Status.Handshaking; @@ -671,8 +656,8 @@ protected void validateTransportParameters(TransportParameters transportParamete } @Override - public InetAddress getInitialClientAddress() { - return initialClientAddress.getAddress(); + public InetSocketAddress getInitialClientAddress() { + return initialClientAddress; } private class TlsMessageSender implements ServerMessageSender { diff --git a/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionRegistryImpl.java b/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionRegistryImpl.java index 3e21d023..cac7bc9c 100644 --- a/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionRegistryImpl.java +++ b/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionRegistryImpl.java @@ -26,11 +26,7 @@ import java.net.InetSocketAddress; import java.security.SecureRandom; import java.time.Duration; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; diff --git a/core/src/main/java/tech/kwik/core/server/impl/ServerConnectorImpl.java b/core/src/main/java/tech/kwik/core/server/impl/ServerConnectorImpl.java index 17f2a7b8..d9a43120 100644 --- a/core/src/main/java/tech/kwik/core/server/impl/ServerConnectorImpl.java +++ b/core/src/main/java/tech/kwik/core/server/impl/ServerConnectorImpl.java @@ -55,11 +55,7 @@ import java.security.spec.InvalidKeySpecException; import java.time.Duration; import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.concurrent.*; import java.util.stream.Collectors; diff --git a/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java b/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java new file mode 100644 index 00000000..5d05fa65 --- /dev/null +++ b/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java @@ -0,0 +1,49 @@ +package tech.kwik.core.stream; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +final class ListenerThreadPool { + + // Static initializers + + private static final List pending = new ArrayList<>(); + private static final ThreadPoolExecutor executor; + + static { + executor = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new ThreadFactory() { + @Override + public Thread newThread(Runnable runnable) { + Thread thread = new Thread(runnable, "kwik-listener"); + thread.setDaemon(true); + + return thread; + } + }); + } + + public static void execute(QuicStreamImpl stream, Runnable runnable) { + if (pending.contains(stream)) { + return; + } + + executor.execute(() -> { + try { + runnable.run(); + } finally { + pending.remove(stream); + } + }); + } + + // Object + + private ListenerThreadPool() { + throw new UnsupportedOperationException("this class cannot be instantiated"); + } + +} diff --git a/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java b/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java index 4bfc0b54..3e1c162d 100644 --- a/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java +++ b/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java @@ -47,7 +47,6 @@ public class QuicStreamImpl implements QuicStream { private volatile boolean inputClosed; private final ReentrantLock stateLock; - public QuicStreamImpl(int streamId, Role role, QuicConnectionImpl connection, StreamManager streamManager, FlowControl flowController) { this(Version.getDefault(), streamId, role, connection, streamManager, flowController, new NullLogger()); } @@ -77,6 +76,7 @@ public QuicStreamImpl(Version quicVersion, int streamId, Role role, QuicConnecti if (isBidirectional() || isUnidirectional() && isSelfInitiated()) { outputStream = createStreamOutputStream(sendBufferSize, flowController); + ((StreamOutputStreamImpl) outputStream).sendBuffer.notifyCanWrite(true); } else { outputStream = new NullStreamOutputStream(); @@ -104,6 +104,13 @@ public OutputStream getOutputStream() { return outputStream; } + public boolean isOutputClosed() { + return outputClosed; + } + public boolean isInputClosed() { + return inputClosed; + } + /** * Adds data from a newly received frame to the stream. * diff --git a/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java b/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java index 6356312c..49799b65 100644 --- a/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java +++ b/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java @@ -40,6 +40,8 @@ public class ReceiveBufferImpl implements ReceiveBuffer { private static final int DEFAULT_MAX_COMBINED_FRAME_SIZE = 5120; + private final QuicStreamImpl stream; + private final NavigableSet outOfOrderFrames = new ConcurrentSkipListSet<>(); private final Queue contiguousFrames = new ConcurrentLinkedQueue<>(); private volatile long contiguousUpToOffset = 0; @@ -49,8 +51,10 @@ public class ReceiveBufferImpl implements ReceiveBuffer { private final int maxCombinedFrameSize; private volatile boolean discarded; - public ReceiveBufferImpl() { - this(DEFAULT_MAX_COMBINED_FRAME_SIZE); + private volatile long lastAvailData = -1; + + public ReceiveBufferImpl(QuicStreamImpl stream) { + this(stream, DEFAULT_MAX_COMBINED_FRAME_SIZE); } /** @@ -64,8 +68,24 @@ public ReceiveBufferImpl() { * @param maxCombinedFrameSize the maximum size of a combined frame (i.e. when frames are combined to remove * overlap, the resulting frame will not be larger than this size). */ - public ReceiveBufferImpl(int maxCombinedFrameSize) { + public ReceiveBufferImpl(QuicStreamImpl stream, int maxCombinedFrameSize) { this.maxCombinedFrameSize = maxCombinedFrameSize; + this.stream = stream; + } + + private void notifyWriter(boolean force) { + if (stream == null || stream.connection == null || stream.connection.readListener == null) return; + if (stream.isInputClosed()) return; + + long avail = bytesAvailable(); + if (force || avail != lastAvailData) { + lastAvailData = avail; + ListenerThreadPool.execute(stream, () -> { + if (!stream.isInputClosed()) { + stream.connection.readListener.read(stream, avail); + } + }); + } } @Override @@ -96,6 +116,8 @@ public int read(ByteBuffer buffer) { nextFrame = contiguousFrames.peek(); } } + + if (totalBytesRead > 0) notifyWriter(false); return totalBytesRead; } @@ -133,9 +155,12 @@ public boolean add(StreamElement frame) { bufferedOutOfOrderData -= nextFrame.getLength(); } } + + // notificar sempre que a quantidade (bytesAvailable) mudar (entrou dado/ficou contíguo/FIN drenou) + notifyWriter(false); + return contiguousUpToOffset > previousContiguousUpToOffset; - } - catch (Exception e) { + } catch (Exception e) { // Because the add method is the only method making modifications to the outOfOrderFrames, race conditions // will not occur. However, there is one exception: the discardAllData method. Concurrent call to this method // can cause a race condition, which can lead to various runtime exceptions in the code block wrapped by this @@ -308,6 +333,7 @@ public void discardAllData() { outOfOrderFrames.clear(); bufferedOutOfOrderData = 0; contiguousFrames.clear(); + notifyWriter(true); } private static class SimpleStreamElement implements StreamElement { @@ -357,7 +383,7 @@ public int compareTo(StreamElement other) { @Override public String toString() { - return "" + offset + ".." + (offset + data.length - 1); + return offset + ".." + (offset + data.length - 1); } } -} +} \ No newline at end of file diff --git a/core/src/main/java/tech/kwik/core/stream/SendBuffer.java b/core/src/main/java/tech/kwik/core/stream/SendBuffer.java index 8e6f4355..ef1ecf0e 100644 --- a/core/src/main/java/tech/kwik/core/stream/SendBuffer.java +++ b/core/src/main/java/tech/kwik/core/stream/SendBuffer.java @@ -23,7 +23,6 @@ import java.io.IOException; import java.nio.ByteBuffer; -import java.util.Arrays; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.atomic.AtomicInteger; @@ -36,6 +35,8 @@ */ public class SendBuffer { + private final QuicStreamImpl stream; + // Send queue contains stream bytes to send in order. The position of the first byte buffer in the queue determines the next byte(s) to send. private final Queue sendQueue; private final ByteBuffer END_OF_STREAM_MARKER = ByteBuffer.allocate(0); @@ -45,8 +46,13 @@ public class SendBuffer { private final Condition notFull; private volatile Thread blockingWriterThread; + private volatile boolean closed = false; + + private volatile int lastReportedAvail = Integer.MIN_VALUE; + private volatile boolean lastReportedWritable = true; - public SendBuffer(Integer sendBufferSize) { + public SendBuffer(QuicStreamImpl stream, Integer sendBufferSize) { + this.stream = stream; sendQueue = new ConcurrentLinkedDeque<>(); if (sendBufferSize != null && sendBufferSize > 0) { maxBufferSize = sendBufferSize; @@ -59,14 +65,29 @@ public SendBuffer(Integer sendBufferSize) { notFull = bufferLock.newCondition(); } + public void notifyCanWrite(boolean force) { + var l = (stream != null && stream.connection != null) ? stream.connection.writeListener : null; // use o listener que você já tem + if (l == null) return; + else if (stream.isOutputClosed()) return; + + int avail = getAvailableBytes(); + boolean canWrite = !closed && avail > 0; + int report = canWrite ? avail : 0; + + if (force || report != lastReportedAvail || canWrite != lastReportedWritable) { + lastReportedAvail = report; + lastReportedWritable = canWrite; + ListenerThreadPool.execute(stream, () -> { + if (!stream.isOutputClosed()) { + l.write(stream, report); + } + }); + } + } + /** * Writes data to the buffer. If the buffer is full, the method will block until there is enough space in the buffer. * This method makes defensive copies of the data. - * @param data - * @param off - * @param len - * @throws IOException - * @throws InterruptedException */ public void write(byte[] data, int off, int len) throws IOException, InterruptedException { int availableBufferSpace = maxBufferSize - bufferedBytes.get(); @@ -89,8 +110,10 @@ public void write(byte[] data, int off, int len) throws IOException, Interrupted } } - sendQueue.add(ByteBuffer.wrap(Arrays.copyOfRange(data, off, off + len))); + sendQueue.add(ByteBuffer.wrap(java.util.Arrays.copyOfRange(data, off, off + len))); bufferedBytes.getAndAdd(len); + + notifyCanWrite(false); } public StreamFrame getStreamFrame(Version quicVersion, int streamId, long currentOffset, int maxBytesToSend) { @@ -130,29 +153,40 @@ public StreamFrame getStreamFrame(Version quicVersion, int streamId, long curren finally { bufferLock.unlock(); } + + notifyCanWrite(false); + if (nrOfBytes < maxBytesToSend) { // This can happen when not enough data is buffer to fill a stream frame, or length field is 1 byte (instead of 2 that was counted for) - dataToSend = Arrays.copyOfRange(dataToSend, 0, nrOfBytes); + dataToSend = java.util.Arrays.copyOfRange(dataToSend, 0, nrOfBytes); } - StreamFrame streamFrame = new StreamFrame(quicVersion, streamId, currentOffset, dataToSend, finalFrame); - return streamFrame; + + return new StreamFrame(quicVersion, streamId, currentOffset, dataToSend, finalFrame); } - public int getAvailableBytes() { + public int getBufferedBytes() { return bufferedBytes.get(); } + public int getAvailableBytes() { + return getMaxSize() - getBufferedBytes(); + } public boolean isEmpty() { return sendQueue.isEmpty(); } - public void close() { - sendQueue.add(END_OF_STREAM_MARKER); - } - public void clear() { sendQueue.clear(); bufferedBytes.set(0); + closed = false; + notifyCanWrite(true); + } + + public void close() { + if (closed) return; + closed = true; + sendQueue.add(END_OF_STREAM_MARKER); + notifyCanWrite(true); } public void interruptBlockedWriter() { diff --git a/core/src/main/java/tech/kwik/core/stream/StreamInputStreamImpl.java b/core/src/main/java/tech/kwik/core/stream/StreamInputStreamImpl.java index a3b0e6a9..d5b1a3be 100644 --- a/core/src/main/java/tech/kwik/core/stream/StreamInputStreamImpl.java +++ b/core/src/main/java/tech/kwik/core/stream/StreamInputStreamImpl.java @@ -61,7 +61,7 @@ class StreamInputStreamImpl extends StreamInputStream { public StreamInputStreamImpl(QuicStreamImpl quicStream, long receiveBufferSize, Logger log) { this.quicStream = quicStream; this.log = log; - receiveBuffer = new ReceiveBufferImpl(); + receiveBuffer = new ReceiveBufferImpl(quicStream); receiverFlowControlLimit = receiveBufferSize; lastCommunicatedMaxData = receiverFlowControlLimit; diff --git a/core/src/main/java/tech/kwik/core/stream/StreamManager.java b/core/src/main/java/tech/kwik/core/stream/StreamManager.java index 1c994e5f..3b86257c 100644 --- a/core/src/main/java/tech/kwik/core/stream/StreamManager.java +++ b/core/src/main/java/tech/kwik/core/stream/StreamManager.java @@ -27,11 +27,7 @@ import tech.kwik.core.log.Logger; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Consumer; diff --git a/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java b/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java index 0e324ea8..1a36dc35 100644 --- a/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java +++ b/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java @@ -19,11 +19,7 @@ package tech.kwik.core.stream; import tech.kwik.core.common.EncryptionLevel; -import tech.kwik.core.frame.DataBlockedFrame; -import tech.kwik.core.frame.QuicFrame; -import tech.kwik.core.frame.ResetStreamFrame; -import tech.kwik.core.frame.StreamDataBlockedFrame; -import tech.kwik.core.frame.StreamFrame; +import tech.kwik.core.frame.*; import tech.kwik.core.log.Logger; import java.io.IOException; @@ -41,7 +37,7 @@ class StreamOutputStreamImpl extends StreamOutputStream implements FlowControlUp private final QuicStreamImpl quicStream; private final Object lock = new Object(); - private final SendBuffer sendBuffer; + public final SendBuffer sendBuffer; private final Logger log; private final int maxBufferSize; private final RetransmitBuffer retransmitBuffer; @@ -64,7 +60,7 @@ class StreamOutputStreamImpl extends StreamOutputStream implements FlowControlUp StreamOutputStreamImpl(QuicStreamImpl quicStream, Integer sendBufferSize, FlowControl flowControl, Logger log) { this.quicStream = quicStream; flowController = flowControl; - sendBuffer = new SendBuffer(sendBufferSize); + sendBuffer = new SendBuffer(quicStream, sendBufferSize); this.log = log; maxBufferSize = sendBuffer.getMaxSize(); retransmitBuffer = new RetransmitBuffer(); @@ -170,7 +166,7 @@ else if (sendBuffer.hasData()) { long flowControlLimit = flowController.getFlowControlLimit(quicStream); assert (flowControlLimit >= currentOffset); - int maxBytesToSend = sendBuffer.getAvailableBytes(); + int maxBytesToSend = sendBuffer.getBufferedBytes(); if (flowControlLimit > currentOffset || maxBytesToSend == 0) { StreamFrame dummy = new StreamFrame(quicStream.quicVersion, quicStream.streamId, currentOffset, new byte[0], false); maxBytesToSend = Integer.min(maxBytesToSend, maxFrameSize - dummy.getFrameLength() - 1); // Take one byte extra for length field var int diff --git a/core/src/test/java/tech/kwik/core/StatisticsTest.java b/core/src/test/java/tech/kwik/core/StatisticsTest.java index b3a1f197..daacf9ee 100644 --- a/core/src/test/java/tech/kwik/core/StatisticsTest.java +++ b/core/src/test/java/tech/kwik/core/StatisticsTest.java @@ -18,8 +18,8 @@ */ package tech.kwik.core; -import tech.kwik.core.send.SendStatistics; import org.junit.jupiter.api.Test; +import tech.kwik.core.send.SendStatistics; import static org.assertj.core.api.Assertions.assertThat; diff --git a/core/src/test/java/tech/kwik/core/cc/CongestionControllerTest.java b/core/src/test/java/tech/kwik/core/cc/CongestionControllerTest.java index fa43dd6c..6164f61e 100644 --- a/core/src/test/java/tech/kwik/core/cc/CongestionControllerTest.java +++ b/core/src/test/java/tech/kwik/core/cc/CongestionControllerTest.java @@ -18,14 +18,14 @@ */ package tech.kwik.core.cc; -import tech.kwik.core.impl.MockPacket; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import tech.kwik.core.frame.AckFrame; import tech.kwik.core.frame.Padding; +import tech.kwik.core.impl.MockPacket; import tech.kwik.core.log.Logger; import tech.kwik.core.packet.PacketInfo; import tech.kwik.core.packet.QuicPacket; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import java.time.Instant; import java.util.List; diff --git a/core/src/test/java/tech/kwik/core/cc/NewRenoCongestionControllerTest.java b/core/src/test/java/tech/kwik/core/cc/NewRenoCongestionControllerTest.java index 5222892c..0592701a 100644 --- a/core/src/test/java/tech/kwik/core/cc/NewRenoCongestionControllerTest.java +++ b/core/src/test/java/tech/kwik/core/cc/NewRenoCongestionControllerTest.java @@ -18,14 +18,14 @@ */ package tech.kwik.core.cc; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import tech.kwik.core.common.EncryptionLevel; -import tech.kwik.core.impl.MockPacket; import tech.kwik.core.frame.Padding; +import tech.kwik.core.impl.MockPacket; import tech.kwik.core.log.NullLogger; import tech.kwik.core.packet.PacketInfo; import tech.kwik.core.packet.QuicPacket; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import java.time.Instant; import java.util.List; diff --git a/core/src/test/java/tech/kwik/core/cid/DestinationConnectionIdRegistryTest.java b/core/src/test/java/tech/kwik/core/cid/DestinationConnectionIdRegistryTest.java index 67cf6285..e3cb5bff 100644 --- a/core/src/test/java/tech/kwik/core/cid/DestinationConnectionIdRegistryTest.java +++ b/core/src/test/java/tech/kwik/core/cid/DestinationConnectionIdRegistryTest.java @@ -18,9 +18,9 @@ */ package tech.kwik.core.cid; -import tech.kwik.core.log.Logger; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import tech.kwik.core.log.Logger; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/core/src/test/java/tech/kwik/core/crypto/ConnectionSecretsTest.java b/core/src/test/java/tech/kwik/core/crypto/ConnectionSecretsTest.java index 74754d6d..552fac03 100644 --- a/core/src/test/java/tech/kwik/core/crypto/ConnectionSecretsTest.java +++ b/core/src/test/java/tech/kwik/core/crypto/ConnectionSecretsTest.java @@ -18,12 +18,12 @@ */ package tech.kwik.core.crypto; +import org.junit.jupiter.api.Test; import tech.kwik.core.common.EncryptionLevel; import tech.kwik.core.impl.Role; import tech.kwik.core.impl.Version; import tech.kwik.core.impl.VersionHolder; import tech.kwik.core.log.Logger; -import org.junit.jupiter.api.Test; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.ThrowableAssert.catchThrowable; diff --git a/core/src/test/java/tech/kwik/core/crypto/CryptoStreamTest.java b/core/src/test/java/tech/kwik/core/crypto/CryptoStreamTest.java index 301154aa..bbb81ece 100644 --- a/core/src/test/java/tech/kwik/core/crypto/CryptoStreamTest.java +++ b/core/src/test/java/tech/kwik/core/crypto/CryptoStreamTest.java @@ -55,9 +55,7 @@ import java.util.function.Function; import java.util.stream.Collectors; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; import static tech.kwik.agent15.TlsConstants.HandshakeType.certificate_request; diff --git a/core/src/test/java/tech/kwik/core/frame/CryptoFrameTest.java b/core/src/test/java/tech/kwik/core/frame/CryptoFrameTest.java index 2250f8db..3854b85e 100644 --- a/core/src/test/java/tech/kwik/core/frame/CryptoFrameTest.java +++ b/core/src/test/java/tech/kwik/core/frame/CryptoFrameTest.java @@ -19,8 +19,8 @@ package tech.kwik.core.frame; -import tech.kwik.core.impl.Version; import org.junit.jupiter.api.Test; +import tech.kwik.core.impl.Version; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/frame/NewConnectionIdFrameTest.java b/core/src/test/java/tech/kwik/core/frame/NewConnectionIdFrameTest.java index 5ed58566..7c3231fb 100644 --- a/core/src/test/java/tech/kwik/core/frame/NewConnectionIdFrameTest.java +++ b/core/src/test/java/tech/kwik/core/frame/NewConnectionIdFrameTest.java @@ -18,8 +18,8 @@ */ package tech.kwik.core.frame; -import tech.kwik.core.impl.Version; import org.junit.jupiter.api.Test; +import tech.kwik.core.impl.Version; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/frame/PaddingTest.java b/core/src/test/java/tech/kwik/core/frame/PaddingTest.java index d861be90..cc1f408d 100644 --- a/core/src/test/java/tech/kwik/core/frame/PaddingTest.java +++ b/core/src/test/java/tech/kwik/core/frame/PaddingTest.java @@ -18,8 +18,8 @@ */ package tech.kwik.core.frame; -import tech.kwik.core.log.Logger; import org.junit.jupiter.api.Test; +import tech.kwik.core.log.Logger; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/frame/RetireConnectionIdFrameTest.java b/core/src/test/java/tech/kwik/core/frame/RetireConnectionIdFrameTest.java index 73510007..e3f016c9 100644 --- a/core/src/test/java/tech/kwik/core/frame/RetireConnectionIdFrameTest.java +++ b/core/src/test/java/tech/kwik/core/frame/RetireConnectionIdFrameTest.java @@ -18,8 +18,8 @@ */ package tech.kwik.core.frame; -import tech.kwik.core.impl.Version; import org.junit.jupiter.api.Test; +import tech.kwik.core.impl.Version; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/frame/StopSendingFrameTest.java b/core/src/test/java/tech/kwik/core/frame/StopSendingFrameTest.java index 6b7e70cc..facfc75c 100644 --- a/core/src/test/java/tech/kwik/core/frame/StopSendingFrameTest.java +++ b/core/src/test/java/tech/kwik/core/frame/StopSendingFrameTest.java @@ -18,8 +18,8 @@ */ package tech.kwik.core.frame; -import tech.kwik.core.impl.Version; import org.junit.jupiter.api.Test; +import tech.kwik.core.impl.Version; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/frame/StreamDataBlockedFrameTest.java b/core/src/test/java/tech/kwik/core/frame/StreamDataBlockedFrameTest.java index faf4cf51..55571c21 100644 --- a/core/src/test/java/tech/kwik/core/frame/StreamDataBlockedFrameTest.java +++ b/core/src/test/java/tech/kwik/core/frame/StreamDataBlockedFrameTest.java @@ -19,8 +19,8 @@ package tech.kwik.core.frame; -import tech.kwik.core.impl.Version; import org.junit.jupiter.api.Test; +import tech.kwik.core.impl.Version; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/frame/StreamFrameTest.java b/core/src/test/java/tech/kwik/core/frame/StreamFrameTest.java index 04725da6..8f7cce5b 100644 --- a/core/src/test/java/tech/kwik/core/frame/StreamFrameTest.java +++ b/core/src/test/java/tech/kwik/core/frame/StreamFrameTest.java @@ -18,9 +18,9 @@ */ package tech.kwik.core.frame; -import tech.kwik.core.log.Logger; import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import tech.kwik.core.log.Logger; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/frame/StreamsBlockedFrameTest.java b/core/src/test/java/tech/kwik/core/frame/StreamsBlockedFrameTest.java index 89249950..087038bf 100644 --- a/core/src/test/java/tech/kwik/core/frame/StreamsBlockedFrameTest.java +++ b/core/src/test/java/tech/kwik/core/frame/StreamsBlockedFrameTest.java @@ -19,8 +19,8 @@ package tech.kwik.core.frame; -import tech.kwik.core.impl.Version; import org.junit.jupiter.api.Test; +import tech.kwik.core.impl.Version; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/impl/EncryptionLevelTest.java b/core/src/test/java/tech/kwik/core/impl/EncryptionLevelTest.java index 6d12b313..95663ff4 100644 --- a/core/src/test/java/tech/kwik/core/impl/EncryptionLevelTest.java +++ b/core/src/test/java/tech/kwik/core/impl/EncryptionLevelTest.java @@ -18,11 +18,11 @@ */ package tech.kwik.core.impl; -import tech.kwik.core.common.EncryptionLevel; import org.junit.jupiter.api.Test; +import tech.kwik.core.common.EncryptionLevel; -import static tech.kwik.core.common.EncryptionLevel.*; import static org.assertj.core.api.Assertions.assertThat; +import static tech.kwik.core.common.EncryptionLevel.*; class EncryptionLevelTest { diff --git a/core/src/test/java/tech/kwik/core/impl/IdleTimerTest.java b/core/src/test/java/tech/kwik/core/impl/IdleTimerTest.java index 63a78f43..21c9eb0f 100644 --- a/core/src/test/java/tech/kwik/core/impl/IdleTimerTest.java +++ b/core/src/test/java/tech/kwik/core/impl/IdleTimerTest.java @@ -18,16 +18,16 @@ */ package tech.kwik.core.impl; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; import tech.kwik.core.frame.PingFrame; import tech.kwik.core.log.Logger; import tech.kwik.core.packet.ShortHeaderPacket; import tech.kwik.core.test.FieldSetter; import tech.kwik.core.test.TestClock; import tech.kwik.core.test.TestScheduledExecutor; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import java.util.concurrent.ScheduledExecutorService; diff --git a/core/src/test/java/tech/kwik/core/impl/KeepAliveActorTest.java b/core/src/test/java/tech/kwik/core/impl/KeepAliveActorTest.java index 49fb852d..7c9bf71a 100644 --- a/core/src/test/java/tech/kwik/core/impl/KeepAliveActorTest.java +++ b/core/src/test/java/tech/kwik/core/impl/KeepAliveActorTest.java @@ -18,14 +18,14 @@ */ package tech.kwik.core.impl; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import tech.kwik.core.common.EncryptionLevel; import tech.kwik.core.frame.PingFrame; import tech.kwik.core.send.Sender; import tech.kwik.core.test.TestClock; import tech.kwik.core.test.TestScheduledExecutor; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import java.util.concurrent.ScheduledExecutorService; diff --git a/core/src/test/java/tech/kwik/core/impl/PacketMatcherByConnectionId.java b/core/src/test/java/tech/kwik/core/impl/PacketMatcherByConnectionId.java index 9b7f9f24..0978007f 100644 --- a/core/src/test/java/tech/kwik/core/impl/PacketMatcherByConnectionId.java +++ b/core/src/test/java/tech/kwik/core/impl/PacketMatcherByConnectionId.java @@ -18,9 +18,9 @@ */ package tech.kwik.core.impl; +import org.mockito.ArgumentMatcher; import tech.kwik.core.packet.QuicPacket; import tech.kwik.core.packet.ShortHeaderPacket; -import org.mockito.ArgumentMatcher; import java.util.Arrays; diff --git a/core/src/test/java/tech/kwik/core/impl/PacketMatcherByFrameClass.java b/core/src/test/java/tech/kwik/core/impl/PacketMatcherByFrameClass.java index 92032856..e9df8027 100644 --- a/core/src/test/java/tech/kwik/core/impl/PacketMatcherByFrameClass.java +++ b/core/src/test/java/tech/kwik/core/impl/PacketMatcherByFrameClass.java @@ -18,8 +18,8 @@ */ package tech.kwik.core.impl; -import tech.kwik.core.packet.QuicPacket; import org.mockito.ArgumentMatcher; +import tech.kwik.core.packet.QuicPacket; public class PacketMatcherByFrameClass implements ArgumentMatcher { diff --git a/core/src/test/java/tech/kwik/core/impl/PacketMatcherByPacketNumber.java b/core/src/test/java/tech/kwik/core/impl/PacketMatcherByPacketNumber.java index 74e771d3..b19a102e 100644 --- a/core/src/test/java/tech/kwik/core/impl/PacketMatcherByPacketNumber.java +++ b/core/src/test/java/tech/kwik/core/impl/PacketMatcherByPacketNumber.java @@ -18,8 +18,8 @@ */ package tech.kwik.core.impl; -import tech.kwik.core.packet.QuicPacket; import org.mockito.ArgumentMatcher; +import tech.kwik.core.packet.QuicPacket; public class PacketMatcherByPacketNumber implements ArgumentMatcher { diff --git a/core/src/test/java/tech/kwik/core/impl/PaddingTest.java b/core/src/test/java/tech/kwik/core/impl/PaddingTest.java index 7d636ba0..049ab26c 100644 --- a/core/src/test/java/tech/kwik/core/impl/PaddingTest.java +++ b/core/src/test/java/tech/kwik/core/impl/PaddingTest.java @@ -18,10 +18,10 @@ */ package tech.kwik.core.impl; -import tech.kwik.core.frame.Padding; -import tech.kwik.core.log.Logger; import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import tech.kwik.core.frame.Padding; +import tech.kwik.core.log.Logger; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/impl/PnSpaceTest.java b/core/src/test/java/tech/kwik/core/impl/PnSpaceTest.java index c673a0ed..172d84c1 100644 --- a/core/src/test/java/tech/kwik/core/impl/PnSpaceTest.java +++ b/core/src/test/java/tech/kwik/core/impl/PnSpaceTest.java @@ -18,11 +18,9 @@ */ package tech.kwik.core.impl; -import tech.kwik.core.common.PnSpace; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; +import tech.kwik.core.common.PnSpace; class PnSpaceTest { diff --git a/core/src/test/java/tech/kwik/core/impl/QuicClientConnectionImplTest.java b/core/src/test/java/tech/kwik/core/impl/QuicClientConnectionImplTest.java index 35eff672..880c2888 100644 --- a/core/src/test/java/tech/kwik/core/impl/QuicClientConnectionImplTest.java +++ b/core/src/test/java/tech/kwik/core/impl/QuicClientConnectionImplTest.java @@ -41,11 +41,7 @@ import tech.kwik.core.packet.*; import tech.kwik.core.send.SenderImpl; import tech.kwik.core.stream.StreamManager; -import tech.kwik.core.test.ByteUtils; -import tech.kwik.core.test.FieldReader; -import tech.kwik.core.test.FieldSetter; -import tech.kwik.core.test.TestClock; -import tech.kwik.core.test.TestScheduledExecutor; +import tech.kwik.core.test.*; import java.io.IOException; import java.net.Inet4Address; diff --git a/core/src/test/java/tech/kwik/core/impl/QuicSessionTicketImplTest.java b/core/src/test/java/tech/kwik/core/impl/QuicSessionTicketImplTest.java index d2eefa61..23d0f825 100644 --- a/core/src/test/java/tech/kwik/core/impl/QuicSessionTicketImplTest.java +++ b/core/src/test/java/tech/kwik/core/impl/QuicSessionTicketImplTest.java @@ -18,10 +18,10 @@ */ package tech.kwik.core.impl; +import org.junit.jupiter.api.Test; import tech.kwik.agent15.NewSessionTicket; import tech.kwik.agent15.TlsConstants; import tech.kwik.agent15.handshake.NewSessionTicketMessage; -import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/core/src/test/java/tech/kwik/core/impl/TestUtils.java b/core/src/test/java/tech/kwik/core/impl/TestUtils.java index bf6ba87c..b40b77c0 100644 --- a/core/src/test/java/tech/kwik/core/impl/TestUtils.java +++ b/core/src/test/java/tech/kwik/core/impl/TestUtils.java @@ -27,11 +27,11 @@ import javax.crypto.Cipher; -import static tech.kwik.core.impl.Version.IETF_draft_29; -import static tech.kwik.core.impl.Version.QUIC_version_1; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static tech.kwik.core.impl.Version.IETF_draft_29; +import static tech.kwik.core.impl.Version.QUIC_version_1; public class TestUtils { diff --git a/core/src/test/java/tech/kwik/core/packet/ClientRolePacketParserTest.java b/core/src/test/java/tech/kwik/core/packet/ClientRolePacketParserTest.java index 87e4ca5e..5c478813 100644 --- a/core/src/test/java/tech/kwik/core/packet/ClientRolePacketParserTest.java +++ b/core/src/test/java/tech/kwik/core/packet/ClientRolePacketParserTest.java @@ -18,6 +18,8 @@ */ package tech.kwik.core.packet; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import tech.kwik.core.crypto.ConnectionSecrets; import tech.kwik.core.impl.InvalidPacketException; import tech.kwik.core.impl.Role; @@ -25,8 +27,6 @@ import tech.kwik.core.impl.VersionHolder; import tech.kwik.core.log.Logger; import tech.kwik.core.test.ByteUtils; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/packet/HandshakePacketTest.java b/core/src/test/java/tech/kwik/core/packet/HandshakePacketTest.java index 3d20e6ef..c55febc2 100644 --- a/core/src/test/java/tech/kwik/core/packet/HandshakePacketTest.java +++ b/core/src/test/java/tech/kwik/core/packet/HandshakePacketTest.java @@ -26,11 +26,7 @@ import tech.kwik.core.crypto.Aead; import tech.kwik.core.crypto.ConnectionSecrets; import tech.kwik.core.frame.*; -import tech.kwik.core.impl.InvalidPacketException; -import tech.kwik.core.impl.Role; -import tech.kwik.core.impl.TestUtils; -import tech.kwik.core.impl.Version; -import tech.kwik.core.impl.VersionHolder; +import tech.kwik.core.impl.*; import tech.kwik.core.log.Logger; import tech.kwik.core.test.ByteUtils; diff --git a/core/src/test/java/tech/kwik/core/packet/LongHeaderPacketTest.java b/core/src/test/java/tech/kwik/core/packet/LongHeaderPacketTest.java index ab286063..32ff531a 100644 --- a/core/src/test/java/tech/kwik/core/packet/LongHeaderPacketTest.java +++ b/core/src/test/java/tech/kwik/core/packet/LongHeaderPacketTest.java @@ -18,8 +18,8 @@ */ package tech.kwik.core.packet; -import tech.kwik.core.impl.Version; import org.junit.jupiter.api.Test; +import tech.kwik.core.impl.Version; import static org.assertj.core.api.Assertions.assertThat; diff --git a/core/src/test/java/tech/kwik/core/packet/RetryPacketTest.java b/core/src/test/java/tech/kwik/core/packet/RetryPacketTest.java index cb155fa7..69f7b8f0 100644 --- a/core/src/test/java/tech/kwik/core/packet/RetryPacketTest.java +++ b/core/src/test/java/tech/kwik/core/packet/RetryPacketTest.java @@ -18,11 +18,11 @@ */ package tech.kwik.core.packet; +import org.junit.jupiter.api.Test; import tech.kwik.core.impl.InvalidPacketException; import tech.kwik.core.impl.Version; import tech.kwik.core.log.Logger; import tech.kwik.core.test.ByteUtils; -import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/packet/ServerRolePacketParserTest.java b/core/src/test/java/tech/kwik/core/packet/ServerRolePacketParserTest.java index e310d7ad..639743f7 100644 --- a/core/src/test/java/tech/kwik/core/packet/ServerRolePacketParserTest.java +++ b/core/src/test/java/tech/kwik/core/packet/ServerRolePacketParserTest.java @@ -18,14 +18,14 @@ */ package tech.kwik.core.packet; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import tech.kwik.core.crypto.ConnectionSecrets; +import tech.kwik.core.crypto.MissingKeysException; import tech.kwik.core.impl.Role; import tech.kwik.core.impl.Version; import tech.kwik.core.impl.VersionHolder; -import tech.kwik.core.crypto.ConnectionSecrets; -import tech.kwik.core.crypto.MissingKeysException; import tech.kwik.core.log.Logger; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/packet/ShortHeaderPacketTest.java b/core/src/test/java/tech/kwik/core/packet/ShortHeaderPacketTest.java index fa9e4796..a8ea2d45 100644 --- a/core/src/test/java/tech/kwik/core/packet/ShortHeaderPacketTest.java +++ b/core/src/test/java/tech/kwik/core/packet/ShortHeaderPacketTest.java @@ -18,12 +18,12 @@ */ package tech.kwik.core.packet; -import tech.kwik.core.impl.TestUtils; -import tech.kwik.core.impl.Version; +import org.junit.jupiter.api.Test; import tech.kwik.core.crypto.Aead; import tech.kwik.core.frame.PingFrame; import tech.kwik.core.frame.StreamFrame; -import org.junit.jupiter.api.Test; +import tech.kwik.core.impl.TestUtils; +import tech.kwik.core.impl.Version; import static org.assertj.core.api.Assertions.assertThat; diff --git a/core/src/test/java/tech/kwik/core/packet/VersionNegotiationPacketTest.java b/core/src/test/java/tech/kwik/core/packet/VersionNegotiationPacketTest.java index 3fbf617a..ef467389 100644 --- a/core/src/test/java/tech/kwik/core/packet/VersionNegotiationPacketTest.java +++ b/core/src/test/java/tech/kwik/core/packet/VersionNegotiationPacketTest.java @@ -18,12 +18,12 @@ */ package tech.kwik.core.packet; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import tech.kwik.core.impl.InvalidPacketException; import tech.kwik.core.impl.Version; import tech.kwik.core.log.Logger; import tech.kwik.core.test.ByteUtils; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; import java.util.stream.Collectors; diff --git a/core/src/test/java/tech/kwik/core/packet/ZeroRttPacketTest.java b/core/src/test/java/tech/kwik/core/packet/ZeroRttPacketTest.java index d5404b96..58694c34 100644 --- a/core/src/test/java/tech/kwik/core/packet/ZeroRttPacketTest.java +++ b/core/src/test/java/tech/kwik/core/packet/ZeroRttPacketTest.java @@ -18,11 +18,11 @@ */ package tech.kwik.core.packet; -import tech.kwik.core.impl.TestUtils; -import tech.kwik.core.impl.Version; +import org.junit.jupiter.api.Test; import tech.kwik.core.frame.QuicFrame; import tech.kwik.core.frame.StreamFrame; -import org.junit.jupiter.api.Test; +import tech.kwik.core.impl.TestUtils; +import tech.kwik.core.impl.Version; import static org.assertj.core.api.Assertions.assertThat; diff --git a/core/src/test/java/tech/kwik/core/receive/ReceiverTest.java b/core/src/test/java/tech/kwik/core/receive/ReceiverTest.java index a9a5bfd7..9b2ddf68 100644 --- a/core/src/test/java/tech/kwik/core/receive/ReceiverTest.java +++ b/core/src/test/java/tech/kwik/core/receive/ReceiverTest.java @@ -18,10 +18,10 @@ */ package tech.kwik.core.receive; -import tech.kwik.core.log.Logger; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import tech.kwik.core.log.Logger; import java.net.DatagramPacket; import java.net.DatagramSocket; diff --git a/core/src/test/java/tech/kwik/core/recovery/RecoveryTests.java b/core/src/test/java/tech/kwik/core/recovery/RecoveryTests.java index 15843f57..0df37720 100644 --- a/core/src/test/java/tech/kwik/core/recovery/RecoveryTests.java +++ b/core/src/test/java/tech/kwik/core/recovery/RecoveryTests.java @@ -18,15 +18,11 @@ */ package tech.kwik.core.recovery; -import tech.kwik.core.impl.Version; import tech.kwik.core.frame.CryptoFrame; import tech.kwik.core.frame.MaxDataFrame; import tech.kwik.core.frame.QuicFrame; -import tech.kwik.core.packet.HandshakePacket; -import tech.kwik.core.packet.InitialPacket; -import tech.kwik.core.packet.LongHeaderPacket; -import tech.kwik.core.packet.QuicPacket; -import tech.kwik.core.packet.ShortHeaderPacket; +import tech.kwik.core.impl.Version; +import tech.kwik.core.packet.*; import tech.kwik.core.test.FieldSetter; import java.time.Instant; diff --git a/core/src/test/java/tech/kwik/core/send/AbstractSenderTest.java b/core/src/test/java/tech/kwik/core/send/AbstractSenderTest.java index 88faf70d..d9a949b3 100644 --- a/core/src/test/java/tech/kwik/core/send/AbstractSenderTest.java +++ b/core/src/test/java/tech/kwik/core/send/AbstractSenderTest.java @@ -18,10 +18,10 @@ */ package tech.kwik.core.send; +import org.junit.jupiter.api.BeforeEach; import tech.kwik.core.common.EncryptionLevel; -import tech.kwik.core.impl.TestUtils; import tech.kwik.core.crypto.Aead; -import org.junit.jupiter.api.BeforeEach; +import tech.kwik.core.impl.TestUtils; public class AbstractSenderTest { diff --git a/core/src/test/java/tech/kwik/core/send/PacketAssemblerTest.java b/core/src/test/java/tech/kwik/core/send/PacketAssemblerTest.java index 9a551a72..715b12a5 100644 --- a/core/src/test/java/tech/kwik/core/send/PacketAssemblerTest.java +++ b/core/src/test/java/tech/kwik/core/send/PacketAssemblerTest.java @@ -42,9 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.data.Percentage.withPercentage; -import static org.mockito.Mockito.argThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.*; class PacketAssemblerTest extends AbstractSenderTest { diff --git a/core/src/test/java/tech/kwik/core/send/SendRequestQueueTest.java b/core/src/test/java/tech/kwik/core/send/SendRequestQueueTest.java index 1b42e4d4..314d13ca 100644 --- a/core/src/test/java/tech/kwik/core/send/SendRequestQueueTest.java +++ b/core/src/test/java/tech/kwik/core/send/SendRequestQueueTest.java @@ -18,14 +18,10 @@ */ package tech.kwik.core.send; -import tech.kwik.core.frame.CryptoFrame; -import tech.kwik.core.frame.DatagramFrame; -import tech.kwik.core.frame.PathResponseFrame; -import tech.kwik.core.frame.QuicFrame; -import tech.kwik.core.frame.StreamFrame; -import tech.kwik.core.impl.Version; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import tech.kwik.core.frame.*; +import tech.kwik.core.impl.Version; import java.time.Duration; import java.time.Instant; diff --git a/core/src/test/java/tech/kwik/core/server/impl/ApplicationProtocolRegistryTest.java b/core/src/test/java/tech/kwik/core/server/impl/ApplicationProtocolRegistryTest.java index ab01c041..1457bee0 100644 --- a/core/src/test/java/tech/kwik/core/server/impl/ApplicationProtocolRegistryTest.java +++ b/core/src/test/java/tech/kwik/core/server/impl/ApplicationProtocolRegistryTest.java @@ -18,9 +18,9 @@ */ package tech.kwik.core.server.impl; +import org.junit.jupiter.api.Test; import tech.kwik.core.impl.QuicConnectionImpl; import tech.kwik.core.server.ApplicationProtocolConnection; -import org.junit.jupiter.api.Test; import java.util.List; import java.util.Optional; diff --git a/core/src/test/java/tech/kwik/core/server/impl/ClientAddressFilterTest.java b/core/src/test/java/tech/kwik/core/server/impl/ClientAddressFilterTest.java index 5c73b793..1600320c 100644 --- a/core/src/test/java/tech/kwik/core/server/impl/ClientAddressFilterTest.java +++ b/core/src/test/java/tech/kwik/core/server/impl/ClientAddressFilterTest.java @@ -28,9 +28,7 @@ import java.time.Instant; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.*; class ClientAddressFilterTest { diff --git a/core/src/test/java/tech/kwik/core/server/impl/ClientInitialScidFilterTest.java b/core/src/test/java/tech/kwik/core/server/impl/ClientInitialScidFilterTest.java index 86a778d8..d6ba58fb 100644 --- a/core/src/test/java/tech/kwik/core/server/impl/ClientInitialScidFilterTest.java +++ b/core/src/test/java/tech/kwik/core/server/impl/ClientInitialScidFilterTest.java @@ -26,9 +26,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.*; class ClientInitialScidFilterTest { diff --git a/core/src/test/java/tech/kwik/core/server/impl/InitialPacketFilterProxyTest.java b/core/src/test/java/tech/kwik/core/server/impl/InitialPacketFilterProxyTest.java index b5c53131..43ade0b4 100644 --- a/core/src/test/java/tech/kwik/core/server/impl/InitialPacketFilterProxyTest.java +++ b/core/src/test/java/tech/kwik/core/server/impl/InitialPacketFilterProxyTest.java @@ -18,10 +18,10 @@ */ package tech.kwik.core.server.impl; -import tech.kwik.core.impl.Version; -import tech.kwik.core.log.LogProxy; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import tech.kwik.core.impl.Version; +import tech.kwik.core.log.LogProxy; import java.nio.ByteBuffer; import java.time.Instant; diff --git a/core/src/test/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilterTest.java b/core/src/test/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilterTest.java index 74fc6cf9..ffa56284 100644 --- a/core/src/test/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilterTest.java +++ b/core/src/test/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilterTest.java @@ -28,9 +28,7 @@ import java.nio.ByteBuffer; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.*; class InitialPacketMinimumSizeFilterTest { diff --git a/core/src/test/java/tech/kwik/core/server/impl/ServerConnectionImplTest.java b/core/src/test/java/tech/kwik/core/server/impl/ServerConnectionImplTest.java index f55e4237..26c118f8 100644 --- a/core/src/test/java/tech/kwik/core/server/impl/ServerConnectionImplTest.java +++ b/core/src/test/java/tech/kwik/core/server/impl/ServerConnectionImplTest.java @@ -47,11 +47,7 @@ import tech.kwik.core.frame.FrameProcessor; import tech.kwik.core.impl.*; import tech.kwik.core.log.Logger; -import tech.kwik.core.packet.HandshakePacket; -import tech.kwik.core.packet.InitialPacket; -import tech.kwik.core.packet.PacketMetaData; -import tech.kwik.core.packet.QuicPacket; -import tech.kwik.core.packet.RetryPacket; +import tech.kwik.core.packet.*; import tech.kwik.core.send.SenderImpl; import tech.kwik.core.server.ApplicationProtocolConnection; import tech.kwik.core.server.ApplicationProtocolConnectionFactory; diff --git a/core/src/test/java/tech/kwik/core/server/impl/ServerConnectorImplTest.java b/core/src/test/java/tech/kwik/core/server/impl/ServerConnectorImplTest.java index 61b16586..276099b2 100644 --- a/core/src/test/java/tech/kwik/core/server/impl/ServerConnectorImplTest.java +++ b/core/src/test/java/tech/kwik/core/server/impl/ServerConnectorImplTest.java @@ -41,11 +41,7 @@ import tech.kwik.core.server.ApplicationProtocolConnectionFactory; import tech.kwik.core.server.ServerConnectionFactory; import tech.kwik.core.server.ServerConnectionRegistry; -import tech.kwik.core.test.ByteUtils; -import tech.kwik.core.test.FieldReader; -import tech.kwik.core.test.FieldSetter; -import tech.kwik.core.test.TestClock; -import tech.kwik.core.test.TestScheduledExecutor; +import tech.kwik.core.test.*; import java.io.InputStream; import java.net.DatagramPacket; diff --git a/core/src/test/java/tech/kwik/core/stream/EarlyDataStreamTest.java b/core/src/test/java/tech/kwik/core/stream/EarlyDataStreamTest.java index 9fbf4a90..64a10f0a 100644 --- a/core/src/test/java/tech/kwik/core/stream/EarlyDataStreamTest.java +++ b/core/src/test/java/tech/kwik/core/stream/EarlyDataStreamTest.java @@ -18,17 +18,17 @@ */ package tech.kwik.core.stream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import tech.kwik.core.common.EncryptionLevel; +import tech.kwik.core.frame.QuicFrame; +import tech.kwik.core.frame.StreamFrame; import tech.kwik.core.impl.QuicClientConnectionImpl; import tech.kwik.core.impl.Role; import tech.kwik.core.impl.Version; -import tech.kwik.core.frame.QuicFrame; -import tech.kwik.core.frame.StreamFrame; import tech.kwik.core.log.Logger; import tech.kwik.core.log.NullLogger; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; import java.io.IOException; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/stream/FlowControlTest.java b/core/src/test/java/tech/kwik/core/stream/FlowControlTest.java index 813afcaf..96567d85 100644 --- a/core/src/test/java/tech/kwik/core/stream/FlowControlTest.java +++ b/core/src/test/java/tech/kwik/core/stream/FlowControlTest.java @@ -18,15 +18,15 @@ */ package tech.kwik.core.stream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import tech.kwik.core.QuicStream; +import tech.kwik.core.frame.MaxDataFrame; +import tech.kwik.core.frame.MaxStreamDataFrame; import tech.kwik.core.impl.QuicConnectionImpl; import tech.kwik.core.impl.Role; import tech.kwik.core.impl.TransportError; import tech.kwik.core.impl.TransportParameters; -import tech.kwik.core.frame.MaxDataFrame; -import tech.kwik.core.frame.MaxStreamDataFrame; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; diff --git a/core/src/test/java/tech/kwik/core/stream/QuicStreamImplTest.java b/core/src/test/java/tech/kwik/core/stream/QuicStreamImplTest.java index 8147e14d..e328c9dc 100644 --- a/core/src/test/java/tech/kwik/core/stream/QuicStreamImplTest.java +++ b/core/src/test/java/tech/kwik/core/stream/QuicStreamImplTest.java @@ -24,11 +24,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import tech.kwik.core.common.EncryptionLevel; -import tech.kwik.core.frame.MaxStreamDataFrame; -import tech.kwik.core.frame.QuicFrame; -import tech.kwik.core.frame.ResetStreamFrame; -import tech.kwik.core.frame.StopSendingFrame; -import tech.kwik.core.frame.StreamFrame; +import tech.kwik.core.frame.*; import tech.kwik.core.generic.IntegerTooLargeException; import tech.kwik.core.generic.InvalidIntegerEncodingException; import tech.kwik.core.impl.QuicConnectionImpl; diff --git a/core/src/test/java/tech/kwik/core/stream/ReceiveBufferImplTest.java b/core/src/test/java/tech/kwik/core/stream/ReceiveBufferImplTest.java index 90352dba..b54392ed 100644 --- a/core/src/test/java/tech/kwik/core/stream/ReceiveBufferImplTest.java +++ b/core/src/test/java/tech/kwik/core/stream/ReceiveBufferImplTest.java @@ -16,7 +16,7 @@ class ReceiveBufferImplTest { @BeforeEach void setUpObjectUnderTest() { - receiveBuffer = new ReceiveBufferImpl(MAX_COMBINED_FRAME_SIZE); + receiveBuffer = new ReceiveBufferImpl(null, MAX_COMBINED_FRAME_SIZE); } @Test diff --git a/core/src/test/java/tech/kwik/core/stream/RetransmitBufferTest.java b/core/src/test/java/tech/kwik/core/stream/RetransmitBufferTest.java index 5102bdb8..75934992 100644 --- a/core/src/test/java/tech/kwik/core/stream/RetransmitBufferTest.java +++ b/core/src/test/java/tech/kwik/core/stream/RetransmitBufferTest.java @@ -19,9 +19,9 @@ package tech.kwik.core.stream; -import tech.kwik.core.frame.StreamFrame; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import tech.kwik.core.frame.StreamFrame; import static org.assertj.core.api.Assertions.assertThat; diff --git a/core/src/test/java/tech/kwik/core/stream/StreamManagerTest.java b/core/src/test/java/tech/kwik/core/stream/StreamManagerTest.java index 4b0c2b3d..412791a0 100644 --- a/core/src/test/java/tech/kwik/core/stream/StreamManagerTest.java +++ b/core/src/test/java/tech/kwik/core/stream/StreamManagerTest.java @@ -18,14 +18,13 @@ */ package tech.kwik.core.stream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import tech.kwik.core.ConnectionConfig; import tech.kwik.core.QuicStream; import tech.kwik.core.common.EncryptionLevel; -import tech.kwik.core.frame.MaxDataFrame; -import tech.kwik.core.frame.MaxStreamsFrame; -import tech.kwik.core.frame.QuicFrame; -import tech.kwik.core.frame.ResetStreamFrame; -import tech.kwik.core.frame.StreamFrame; +import tech.kwik.core.frame.*; import tech.kwik.core.impl.QuicConnectionImpl; import tech.kwik.core.impl.Role; import tech.kwik.core.impl.TransportError; @@ -34,9 +33,6 @@ import tech.kwik.core.test.FieldReader; import tech.kwik.core.test.TestClock; import tech.kwik.core.test.TestScheduledExecutor; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; import java.util.ArrayList; import java.util.HashMap; @@ -48,15 +44,11 @@ import java.util.function.Consumer; import java.util.function.Function; -import static tech.kwik.core.QuicConstants.TransportErrorCode.FINAL_SIZE_ERROR; -import static tech.kwik.core.QuicConstants.TransportErrorCode.FLOW_CONTROL_ERROR; -import static tech.kwik.core.QuicConstants.TransportErrorCode.STREAM_LIMIT_ERROR; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.*; +import static tech.kwik.core.QuicConstants.TransportErrorCode.*; class StreamManagerTest { diff --git a/core/src/test/java/tech/kwik/core/test/TestClock.java b/core/src/test/java/tech/kwik/core/test/TestClock.java index 630a484c..b0e7bdd8 100644 --- a/core/src/test/java/tech/kwik/core/test/TestClock.java +++ b/core/src/test/java/tech/kwik/core/test/TestClock.java @@ -18,11 +18,7 @@ */ package tech.kwik.core.test; -import java.time.Clock; -import java.time.Duration; -import java.time.Instant; -import java.time.ZoneId; -import java.time.ZoneOffset; +import java.time.*; import java.time.temporal.TemporalAmount; import java.util.ArrayList; import java.util.List; diff --git a/core/src/test/java/tech/kwik/core/tls/ClientHelloBuilder.java b/core/src/test/java/tech/kwik/core/tls/ClientHelloBuilder.java index 0149abe0..1e0451c8 100644 --- a/core/src/test/java/tech/kwik/core/tls/ClientHelloBuilder.java +++ b/core/src/test/java/tech/kwik/core/tls/ClientHelloBuilder.java @@ -18,13 +18,13 @@ */ package tech.kwik.core.tls; -import tech.kwik.core.test.ByteUtils; +import org.junit.jupiter.api.Test; import tech.kwik.agent15.ProtectionKeysType; import tech.kwik.agent15.TlsConstants; import tech.kwik.agent15.engine.MessageProcessor; import tech.kwik.agent15.engine.TlsMessageParser; import tech.kwik.agent15.handshake.HandshakeMessage; -import org.junit.jupiter.api.Test; +import tech.kwik.core.test.ByteUtils; import java.nio.ByteBuffer; import java.util.ArrayList; diff --git a/h09/src/main/java/module-info.java b/h09/src/main/java/module-info.java index 62cc0626..514441c0 100644 --- a/h09/src/main/java/module-info.java +++ b/h09/src/main/java/module-info.java @@ -1,6 +1,7 @@ module tech.kwik.h09 { requires tech.kwik.core; requires java.net.http; + requires java.naming; exports tech.kwik.h09.client; } \ No newline at end of file diff --git a/h09/src/main/java/tech/kwik/h09/io/LimitExceededException.java b/h09/src/main/java/tech/kwik/h09/io/LimitExceededException.java index 84cd4422..e05f669f 100644 --- a/h09/src/main/java/tech/kwik/h09/io/LimitExceededException.java +++ b/h09/src/main/java/tech/kwik/h09/io/LimitExceededException.java @@ -1,28 +1,9 @@ -/* - * Copyright © 2019, 2020, 2021, 2022, 2023, 2024, 2025 Peter Doornbosch - * - * This file is part of Kwik, an implementation of the QUIC protocol in Java. - * - * Kwik is free software: you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your option) - * any later version. - * - * Kwik is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ package tech.kwik.h09.io; import java.io.IOException; public class LimitExceededException extends IOException { - public LimitExceededException(long limit) { super("Limit of " + limit + " bytes is exceeded"); } -} +} \ No newline at end of file diff --git a/h09/src/main/java/tech/kwik/h09/io/LimitedInputStream.java b/h09/src/main/java/tech/kwik/h09/io/LimitedInputStream.java index a1c05920..8f38c77d 100644 --- a/h09/src/main/java/tech/kwik/h09/io/LimitedInputStream.java +++ b/h09/src/main/java/tech/kwik/h09/io/LimitedInputStream.java @@ -42,8 +42,7 @@ public int read() throws IOException { int read = super.read(); bytesRead++; return read; - } - else { + } else { throw new LimitExceededException(limit); } diff --git a/h09/src/main/java/tech/kwik/h09/server/Http09Connection.java b/h09/src/main/java/tech/kwik/h09/server/Http09Connection.java index c6604eac..29e4d340 100644 --- a/h09/src/main/java/tech/kwik/h09/server/Http09Connection.java +++ b/h09/src/main/java/tech/kwik/h09/server/Http09Connection.java @@ -18,11 +18,7 @@ */ package tech.kwik.h09.server; -import tech.kwik.core.KwikVersion; -import tech.kwik.core.QuicConnection; -import tech.kwik.core.QuicConstants; -import tech.kwik.core.QuicStream; -import tech.kwik.core.StreamClosedException; +import tech.kwik.core.*; import tech.kwik.core.server.ApplicationProtocolConnection; import tech.kwik.h09.io.LimitExceededException; import tech.kwik.h09.io.LimitedInputStream; diff --git a/h09/src/test/java/tech/kwik/h09/server/Http09ConnectionTest.java b/h09/src/test/java/tech/kwik/h09/server/Http09ConnectionTest.java index 35603c72..594ef6ee 100644 --- a/h09/src/test/java/tech/kwik/h09/server/Http09ConnectionTest.java +++ b/h09/src/test/java/tech/kwik/h09/server/Http09ConnectionTest.java @@ -18,16 +18,12 @@ */ package tech.kwik.h09.server; -import tech.kwik.core.QuicConnection; -import tech.kwik.core.QuicStream; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import tech.kwik.core.QuicConnection; +import tech.kwik.core.QuicStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/interop/src/main/java/tech/kwik/interop/InteropClient.java b/interop/src/main/java/tech/kwik/interop/InteropClient.java index b4ef7aa8..5f2432fd 100644 --- a/interop/src/main/java/tech/kwik/interop/InteropClient.java +++ b/interop/src/main/java/tech/kwik/interop/InteropClient.java @@ -22,11 +22,11 @@ import tech.kwik.core.QuicConnection; import tech.kwik.core.QuicSessionTicket; import tech.kwik.core.QuicStream; -import tech.kwik.h09.client.Http09Client; import tech.kwik.core.impl.QuicClientConnectionImpl; import tech.kwik.core.log.FileLogger; import tech.kwik.core.log.Logger; import tech.kwik.core.log.NullLogger; +import tech.kwik.h09.client.Http09Client; import java.io.File; import java.io.FileOutputStream; diff --git a/interop/src/main/java/tech/kwik/interop/InteropServer.java b/interop/src/main/java/tech/kwik/interop/InteropServer.java index 559d72eb..cf074691 100644 --- a/interop/src/main/java/tech/kwik/interop/InteropServer.java +++ b/interop/src/main/java/tech/kwik/interop/InteropServer.java @@ -18,11 +18,7 @@ */ package tech.kwik.interop; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.*; import tech.kwik.core.KwikVersion; import tech.kwik.core.QuicConnection; import tech.kwik.core.log.FileLogger; diff --git a/qlog/src/main/java/tech/kwik/qlog/ConnectionQLog.java b/qlog/src/main/java/tech/kwik/qlog/ConnectionQLog.java index 2c120a29..9472dc1c 100644 --- a/qlog/src/main/java/tech/kwik/qlog/ConnectionQLog.java +++ b/qlog/src/main/java/tech/kwik/qlog/ConnectionQLog.java @@ -26,11 +26,7 @@ import tech.kwik.core.util.Bytes; import tech.kwik.qlog.event.*; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; +import java.io.*; import java.time.Duration; import java.time.Instant; import java.util.Map; diff --git a/qlog/src/main/java/tech/kwik/qlog/QLogFrontEnd.java b/qlog/src/main/java/tech/kwik/qlog/QLogFrontEnd.java index bc3c93c1..1411377b 100644 --- a/qlog/src/main/java/tech/kwik/qlog/QLogFrontEnd.java +++ b/qlog/src/main/java/tech/kwik/qlog/QLogFrontEnd.java @@ -24,11 +24,7 @@ import java.io.File; import java.time.Instant; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Queue; -import java.util.Random; +import java.util.*; /** * Entrypoint of the QLog module. Collects qlog events and processes them asynchronously. diff --git a/qlog/src/main/java/tech/kwik/qlog/event/PacketSentEvent.java b/qlog/src/main/java/tech/kwik/qlog/event/PacketSentEvent.java index df47b6b5..be909d80 100644 --- a/qlog/src/main/java/tech/kwik/qlog/event/PacketSentEvent.java +++ b/qlog/src/main/java/tech/kwik/qlog/event/PacketSentEvent.java @@ -1,21 +1,3 @@ -/* - * Copyright © 2020, 2021, 2022, 2023, 2024, 2025 Peter Doornbosch - * - * This file is part of Kwik, an implementation of the QUIC protocol in Java. - * - * Kwik is free software: you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your option) - * any later version. - * - * Kwik is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ package tech.kwik.qlog.event; import tech.kwik.core.packet.QuicPacket; @@ -32,4 +14,4 @@ public void accept(QLogEventProcessor processor) { processor.process(this); } -} +} \ No newline at end of file From 63161fa78221d72b31cfb67e06668cb2a1f8902c Mon Sep 17 00:00:00 2001 From: Mahied Maruf Date: Wed, 31 Dec 2025 20:05:12 +0000 Subject: [PATCH 02/17] Add back stripped license header The license header was stripped, a violation of @ptrd's copyright by distributing this code. The diff of the related commit was quite large, but it appeared to not have any other similar violations, so I believe this is the only one. Related-to: 95504d9b7778db3f63dd17cd10d574d9c63c16da Signed-off-by: Mahied Maruf --- .../tech/kwik/qlog/event/PacketSentEvent.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/qlog/src/main/java/tech/kwik/qlog/event/PacketSentEvent.java b/qlog/src/main/java/tech/kwik/qlog/event/PacketSentEvent.java index be909d80..df47b6b5 100644 --- a/qlog/src/main/java/tech/kwik/qlog/event/PacketSentEvent.java +++ b/qlog/src/main/java/tech/kwik/qlog/event/PacketSentEvent.java @@ -1,3 +1,21 @@ +/* + * Copyright © 2020, 2021, 2022, 2023, 2024, 2025 Peter Doornbosch + * + * This file is part of Kwik, an implementation of the QUIC protocol in Java. + * + * Kwik is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Kwik is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ package tech.kwik.qlog.event; import tech.kwik.core.packet.QuicPacket; @@ -14,4 +32,4 @@ public void accept(QLogEventProcessor processor) { processor.process(this); } -} \ No newline at end of file +} From 4af612916615fed9b62044e5ad499457388f9d94 Mon Sep 17 00:00:00 2001 From: Mechite Date: Tue, 13 Jan 2026 03:49:34 +0000 Subject: [PATCH 03/17] Revert portions of "done changes" This reverts commit 95504d9b7778db3f63dd17cd10d574d9c63c16da. Signed-off-by: Mahied Maruf --- .idea/.gitignore | 3 - .idea/.name | 1 - .idea/compiler.xml | 15 --- .idea/encodings.xml | 7 - .idea/gradle.xml | 24 ---- .idea/inspectionProfiles/Project_Default.xml | 19 --- .idea/jarRepositories.xml | 20 --- .idea/misc.xml | 16 --- .idea/uiDesigner.xml | 124 ------------------ .idea/vcs.xml | 6 - .../java/tech/kwik/cli/InteractiveShell.java | 6 +- cli/src/main/java/tech/kwik/cli/KwikCli.java | 17 ++- core/src/main/java/module-info.java | 1 - .../tech/kwik/core/QuicSessionTicket.java | 2 +- .../kwik/core/cid/ConnectionIdManager.java | 4 +- .../java/tech/kwik/core/crypto/Aes128Gcm.java | 6 +- .../java/tech/kwik/core/crypto/ChaCha20.java | 6 +- .../core/impl/QuicClientConnectionImpl.java | 26 +++- .../kwik/core/impl/QuicConnectionImpl.java | 4 +- .../kwik/core/impl/QuicSessionTicketImpl.java | 2 +- .../java/tech/kwik/core/log/FileLogger.java | 6 +- .../core/packet/ClientRolePacketParser.java | 10 +- .../core/packet/ServerRolePacketParser.java | 6 +- .../kwik/core/packet/ShortHeaderPacket.java | 6 +- .../kwik/core/recovery/RecoveryManager.java | 6 +- .../kwik/core/send/GlobalPacketAssembler.java | 12 +- .../core/send/InitialPacketAssembler.java | 2 +- .../java/tech/kwik/core/send/SenderImpl.java | 6 +- .../impl/InitialPacketMinimumSizeFilter.java | 6 +- .../server/impl/ServerConnectionImpl.java | 23 +++- .../impl/ServerConnectionRegistryImpl.java | 6 +- .../core/server/impl/ServerConnectorImpl.java | 6 +- .../tech/kwik/core/stream/StreamManager.java | 6 +- .../java/tech/kwik/core/StatisticsTest.java | 2 +- .../core/cc/CongestionControllerTest.java | 6 +- .../cc/NewRenoCongestionControllerTest.java | 6 +- .../DestinationConnectionIdRegistryTest.java | 2 +- .../core/crypto/ConnectionSecretsTest.java | 2 +- .../kwik/core/crypto/CryptoStreamTest.java | 4 +- .../tech/kwik/core/frame/CryptoFrameTest.java | 2 +- .../core/frame/NewConnectionIdFrameTest.java | 2 +- .../tech/kwik/core/frame/PaddingTest.java | 2 +- .../frame/RetireConnectionIdFrameTest.java | 2 +- .../kwik/core/frame/StopSendingFrameTest.java | 2 +- .../frame/StreamDataBlockedFrameTest.java | 2 +- .../tech/kwik/core/frame/StreamFrameTest.java | 2 +- .../core/frame/StreamsBlockedFrameTest.java | 2 +- .../kwik/core/impl/EncryptionLevelTest.java | 4 +- .../tech/kwik/core/impl/IdleTimerTest.java | 8 +- .../kwik/core/impl/KeepAliveActorTest.java | 6 +- .../impl/PacketMatcherByConnectionId.java | 2 +- .../core/impl/PacketMatcherByFrameClass.java | 2 +- .../impl/PacketMatcherByPacketNumber.java | 2 +- .../java/tech/kwik/core/impl/PaddingTest.java | 4 +- .../java/tech/kwik/core/impl/PnSpaceTest.java | 4 +- .../impl/QuicClientConnectionImplTest.java | 6 +- .../core/impl/QuicSessionTicketImplTest.java | 2 +- .../java/tech/kwik/core/impl/TestUtils.java | 4 +- .../packet/ClientRolePacketParserTest.java | 4 +- .../kwik/core/packet/HandshakePacketTest.java | 6 +- .../core/packet/LongHeaderPacketTest.java | 2 +- .../kwik/core/packet/RetryPacketTest.java | 2 +- .../packet/ServerRolePacketParserTest.java | 8 +- .../core/packet/ShortHeaderPacketTest.java | 6 +- .../packet/VersionNegotiationPacketTest.java | 4 +- .../kwik/core/packet/ZeroRttPacketTest.java | 6 +- .../tech/kwik/core/receive/ReceiverTest.java | 2 +- .../kwik/core/recovery/RecoveryTests.java | 8 +- .../kwik/core/send/AbstractSenderTest.java | 4 +- .../kwik/core/send/PacketAssemblerTest.java | 4 +- .../kwik/core/send/SendRequestQueueTest.java | 8 +- .../impl/ApplicationProtocolRegistryTest.java | 2 +- .../server/impl/ClientAddressFilterTest.java | 4 +- .../impl/ClientInitialScidFilterTest.java | 4 +- .../impl/InitialPacketFilterProxyTest.java | 4 +- .../InitialPacketMinimumSizeFilterTest.java | 4 +- .../server/impl/ServerConnectionImplTest.java | 6 +- .../server/impl/ServerConnectorImplTest.java | 6 +- .../kwik/core/stream/EarlyDataStreamTest.java | 10 +- .../kwik/core/stream/FlowControlTest.java | 8 +- .../kwik/core/stream/QuicStreamImplTest.java | 6 +- .../core/stream/RetransmitBufferTest.java | 2 +- .../kwik/core/stream/StreamManagerTest.java | 20 ++- .../java/tech/kwik/core/test/TestClock.java | 6 +- .../kwik/core/tls/ClientHelloBuilder.java | 4 +- .../kwik/h09/io/LimitExceededException.java | 21 ++- .../tech/kwik/h09/io/LimitedInputStream.java | 3 +- .../kwik/h09/server/Http09Connection.java | 6 +- .../kwik/h09/server/Http09ConnectionTest.java | 10 +- .../java/tech/kwik/interop/InteropClient.java | 2 +- .../java/tech/kwik/interop/InteropServer.java | 6 +- .../java/tech/kwik/qlog/ConnectionQLog.java | 6 +- .../java/tech/kwik/qlog/QLogFrontEnd.java | 6 +- .../tech/kwik/qlog/event/PacketSentEvent.java | 20 ++- 94 files changed, 349 insertions(+), 373 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/.name delete mode 100644 .idea/compiler.xml delete mode 100644 .idea/encodings.xml delete mode 100644 .idea/gradle.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/jarRepositories.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/uiDesigner.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d33521..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index af541b14..00000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -kwik \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 85d78733..00000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index aa00ffab..00000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 8c30cb87..00000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 886b10d7..00000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index 712ab9d9..00000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index bf80b57a..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml deleted file mode 100644 index 2b63946d..00000000 --- a/.idea/uiDesigner.xml +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddf..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/cli/src/main/java/tech/kwik/cli/InteractiveShell.java b/cli/src/main/java/tech/kwik/cli/InteractiveShell.java index c76b34fb..4b6bbc77 100644 --- a/cli/src/main/java/tech/kwik/cli/InteractiveShell.java +++ b/cli/src/main/java/tech/kwik/cli/InteractiveShell.java @@ -42,7 +42,11 @@ import java.nio.file.Path; import java.time.Duration; import java.time.Instant; -import java.util.*; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; import java.util.stream.Collectors; diff --git a/cli/src/main/java/tech/kwik/cli/KwikCli.java b/cli/src/main/java/tech/kwik/cli/KwikCli.java index 4f1110e6..99fc1720 100644 --- a/cli/src/main/java/tech/kwik/cli/KwikCli.java +++ b/cli/src/main/java/tech/kwik/cli/KwikCli.java @@ -35,10 +35,18 @@ import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.X509ExtendedKeyManager; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.net.*; +import java.net.InetSocketAddress; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; @@ -49,7 +57,10 @@ import java.nio.file.StandardOpenOption; import java.security.*; import java.security.cert.Certificate; -import java.security.cert.*; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.time.Duration; diff --git a/core/src/main/java/module-info.java b/core/src/main/java/module-info.java index afdcbafe..49d09156 100644 --- a/core/src/main/java/module-info.java +++ b/core/src/main/java/module-info.java @@ -3,7 +3,6 @@ requires at.favre.lib.hkdf; requires io.whitfin.siphash; requires java.management; - requires java.compiler; exports tech.kwik.core; exports tech.kwik.core.concurrent; diff --git a/core/src/main/java/tech/kwik/core/QuicSessionTicket.java b/core/src/main/java/tech/kwik/core/QuicSessionTicket.java index a2fc03e7..e2e032b4 100644 --- a/core/src/main/java/tech/kwik/core/QuicSessionTicket.java +++ b/core/src/main/java/tech/kwik/core/QuicSessionTicket.java @@ -18,9 +18,9 @@ */ package tech.kwik.core; +import tech.kwik.core.impl.TransportParameters; import tech.kwik.agent15.NewSessionTicket; import tech.kwik.agent15.TlsConstants; -import tech.kwik.core.impl.TransportParameters; public interface QuicSessionTicket { diff --git a/core/src/main/java/tech/kwik/core/cid/ConnectionIdManager.java b/core/src/main/java/tech/kwik/core/cid/ConnectionIdManager.java index 34e9df5a..70d4cc64 100644 --- a/core/src/main/java/tech/kwik/core/cid/ConnectionIdManager.java +++ b/core/src/main/java/tech/kwik/core/cid/ConnectionIdManager.java @@ -34,7 +34,9 @@ import java.util.function.BiConsumer; import java.util.stream.Stream; -import static tech.kwik.core.QuicConstants.TransportErrorCode.*; +import static tech.kwik.core.QuicConstants.TransportErrorCode.CONNECTION_ID_LIMIT_ERROR; +import static tech.kwik.core.QuicConstants.TransportErrorCode.FRAME_ENCODING_ERROR; +import static tech.kwik.core.QuicConstants.TransportErrorCode.PROTOCOL_VIOLATION; import static tech.kwik.core.common.EncryptionLevel.App; /** diff --git a/core/src/main/java/tech/kwik/core/crypto/Aes128Gcm.java b/core/src/main/java/tech/kwik/core/crypto/Aes128Gcm.java index 11ed2ea1..75542379 100644 --- a/core/src/main/java/tech/kwik/core/crypto/Aes128Gcm.java +++ b/core/src/main/java/tech/kwik/core/crypto/Aes128Gcm.java @@ -7,7 +7,11 @@ import tech.kwik.core.impl.Version; import tech.kwik.core.log.Logger; -import javax.crypto.*; +import javax.crypto.AEADBadTagException; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.InvalidAlgorithmParameterException; diff --git a/core/src/main/java/tech/kwik/core/crypto/ChaCha20.java b/core/src/main/java/tech/kwik/core/crypto/ChaCha20.java index b9feee09..19abbb01 100644 --- a/core/src/main/java/tech/kwik/core/crypto/ChaCha20.java +++ b/core/src/main/java/tech/kwik/core/crypto/ChaCha20.java @@ -25,7 +25,11 @@ import tech.kwik.core.impl.Version; import tech.kwik.core.log.Logger; -import javax.crypto.*; +import javax.crypto.AEADBadTagException; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.ChaCha20ParameterSpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; diff --git a/core/src/main/java/tech/kwik/core/impl/QuicClientConnectionImpl.java b/core/src/main/java/tech/kwik/core/impl/QuicClientConnectionImpl.java index f5d2e812..98dcf92a 100644 --- a/core/src/main/java/tech/kwik/core/impl/QuicClientConnectionImpl.java +++ b/core/src/main/java/tech/kwik/core/impl/QuicClientConnectionImpl.java @@ -21,7 +21,11 @@ import tech.kwik.agent15.NewSessionTicket; import tech.kwik.agent15.TlsConstants; import tech.kwik.agent15.TlsProtocolException; -import tech.kwik.agent15.engine.*; +import tech.kwik.agent15.engine.CertificateWithPrivateKey; +import tech.kwik.agent15.engine.ClientMessageSender; +import tech.kwik.agent15.engine.TlsClientEngine; +import tech.kwik.agent15.engine.TlsClientEngineFactory; +import tech.kwik.agent15.engine.TlsStatusEventHandler; import tech.kwik.agent15.extension.ApplicationLayerProtocolNegotiationExtension; import tech.kwik.agent15.extension.EarlyDataExtension; import tech.kwik.agent15.extension.Extension; @@ -51,12 +55,20 @@ import tech.kwik.core.util.Bytes; import tech.kwik.core.util.InetTools; -import javax.net.ssl.*; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509ExtendedKeyManager; +import javax.net.ssl.X509TrustManager; import java.io.IOException; import java.net.*; import java.nio.ByteBuffer; import java.nio.file.Path; -import java.security.*; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.UnrecoverableKeyException; import java.security.cert.X509Certificate; import java.time.Duration; import java.time.Instant; @@ -70,8 +82,12 @@ import static tech.kwik.agent15.TlsConstants.SignatureScheme.*; import static tech.kwik.core.QuicConstants.TransportErrorCode.*; -import static tech.kwik.core.common.EncryptionLevel.*; -import static tech.kwik.core.impl.QuicClientConnectionImpl.EarlyDataStatus.*; +import static tech.kwik.core.common.EncryptionLevel.App; +import static tech.kwik.core.common.EncryptionLevel.Handshake; +import static tech.kwik.core.common.EncryptionLevel.Initial; +import static tech.kwik.core.impl.QuicClientConnectionImpl.EarlyDataStatus.Accepted; +import static tech.kwik.core.impl.QuicClientConnectionImpl.EarlyDataStatus.None; +import static tech.kwik.core.impl.QuicClientConnectionImpl.EarlyDataStatus.Requested; import static tech.kwik.core.util.Bytes.bytesToHex; diff --git a/core/src/main/java/tech/kwik/core/impl/QuicConnectionImpl.java b/core/src/main/java/tech/kwik/core/impl/QuicConnectionImpl.java index cced43c8..4cc1cb35 100644 --- a/core/src/main/java/tech/kwik/core/impl/QuicConnectionImpl.java +++ b/core/src/main/java/tech/kwik/core/impl/QuicConnectionImpl.java @@ -55,7 +55,9 @@ import static tech.kwik.core.ConnectionTerminatedEvent.CloseReason; import static tech.kwik.core.ConnectionTerminatedEvent.CloseReason.ConnectionLost; import static tech.kwik.core.QuicConstants.TransportErrorCode.*; -import static tech.kwik.core.common.EncryptionLevel.*; +import static tech.kwik.core.common.EncryptionLevel.App; +import static tech.kwik.core.common.EncryptionLevel.Handshake; +import static tech.kwik.core.common.EncryptionLevel.Initial; import static tech.kwik.core.impl.QuicConnectionImpl.ErrorType.APPLICATION_ERROR; import static tech.kwik.core.impl.QuicConnectionImpl.ErrorType.QUIC_LAYER_ERROR; import static tech.kwik.core.send.Sender.NO_RETRANSMIT; diff --git a/core/src/main/java/tech/kwik/core/impl/QuicSessionTicketImpl.java b/core/src/main/java/tech/kwik/core/impl/QuicSessionTicketImpl.java index 8e77e061..607bad49 100644 --- a/core/src/main/java/tech/kwik/core/impl/QuicSessionTicketImpl.java +++ b/core/src/main/java/tech/kwik/core/impl/QuicSessionTicketImpl.java @@ -18,9 +18,9 @@ */ package tech.kwik.core.impl; +import tech.kwik.core.QuicSessionTicket; import tech.kwik.agent15.NewSessionTicket; import tech.kwik.agent15.TlsConstants; -import tech.kwik.core.QuicSessionTicket; import java.nio.ByteBuffer; diff --git a/core/src/main/java/tech/kwik/core/log/FileLogger.java b/core/src/main/java/tech/kwik/core/log/FileLogger.java index 10cacee1..8941e5e6 100644 --- a/core/src/main/java/tech/kwik/core/log/FileLogger.java +++ b/core/src/main/java/tech/kwik/core/log/FileLogger.java @@ -18,7 +18,11 @@ */ package tech.kwik.core.log; -import java.io.*; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; import java.nio.ByteBuffer; diff --git a/core/src/main/java/tech/kwik/core/packet/ClientRolePacketParser.java b/core/src/main/java/tech/kwik/core/packet/ClientRolePacketParser.java index e2298317..cee6f5b1 100644 --- a/core/src/main/java/tech/kwik/core/packet/ClientRolePacketParser.java +++ b/core/src/main/java/tech/kwik/core/packet/ClientRolePacketParser.java @@ -18,19 +18,21 @@ */ package tech.kwik.core.packet; -import tech.kwik.core.crypto.Aead; -import tech.kwik.core.crypto.ConnectionSecrets; -import tech.kwik.core.crypto.MissingKeysException; import tech.kwik.core.impl.InvalidPacketException; import tech.kwik.core.impl.Role; import tech.kwik.core.impl.VersionHolder; +import tech.kwik.core.crypto.Aead; +import tech.kwik.core.crypto.ConnectionSecrets; +import tech.kwik.core.crypto.MissingKeysException; import tech.kwik.core.log.Logger; import tech.kwik.core.log.NullLogger; import java.nio.ByteBuffer; import java.util.function.BiFunction; -import static tech.kwik.core.common.EncryptionLevel.*; +import static tech.kwik.core.common.EncryptionLevel.App; +import static tech.kwik.core.common.EncryptionLevel.Handshake; +import static tech.kwik.core.common.EncryptionLevel.Initial; /** * Packet parser for endpoint that has client role. diff --git a/core/src/main/java/tech/kwik/core/packet/ServerRolePacketParser.java b/core/src/main/java/tech/kwik/core/packet/ServerRolePacketParser.java index ec88ec8b..0e271bc7 100644 --- a/core/src/main/java/tech/kwik/core/packet/ServerRolePacketParser.java +++ b/core/src/main/java/tech/kwik/core/packet/ServerRolePacketParser.java @@ -25,7 +25,11 @@ import tech.kwik.core.generic.IntegerTooLargeException; import tech.kwik.core.generic.InvalidIntegerEncodingException; import tech.kwik.core.generic.VariableLengthInteger; -import tech.kwik.core.impl.*; +import tech.kwik.core.impl.InvalidPacketException; +import tech.kwik.core.impl.QuicConnectionImpl; +import tech.kwik.core.impl.Role; +import tech.kwik.core.impl.TransportError; +import tech.kwik.core.impl.VersionHolder; import tech.kwik.core.log.Logger; import java.nio.ByteBuffer; diff --git a/core/src/main/java/tech/kwik/core/packet/ShortHeaderPacket.java b/core/src/main/java/tech/kwik/core/packet/ShortHeaderPacket.java index 5e774f51..641ab94a 100644 --- a/core/src/main/java/tech/kwik/core/packet/ShortHeaderPacket.java +++ b/core/src/main/java/tech/kwik/core/packet/ShortHeaderPacket.java @@ -23,7 +23,11 @@ import tech.kwik.core.common.PnSpace; import tech.kwik.core.crypto.Aead; import tech.kwik.core.frame.QuicFrame; -import tech.kwik.core.impl.*; +import tech.kwik.core.impl.DecryptionException; +import tech.kwik.core.impl.InvalidPacketException; +import tech.kwik.core.impl.PacketProcessor; +import tech.kwik.core.impl.TransportError; +import tech.kwik.core.impl.Version; import tech.kwik.core.log.Logger; import tech.kwik.core.util.Bytes; diff --git a/core/src/main/java/tech/kwik/core/recovery/RecoveryManager.java b/core/src/main/java/tech/kwik/core/recovery/RecoveryManager.java index 715de8c8..ca503240 100644 --- a/core/src/main/java/tech/kwik/core/recovery/RecoveryManager.java +++ b/core/src/main/java/tech/kwik/core/recovery/RecoveryManager.java @@ -34,7 +34,11 @@ import tech.kwik.core.packet.QuicPacket; import tech.kwik.core.send.Sender; -import java.time.*; +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalTime; +import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Collections; import java.util.List; diff --git a/core/src/main/java/tech/kwik/core/send/GlobalPacketAssembler.java b/core/src/main/java/tech/kwik/core/send/GlobalPacketAssembler.java index 8cc85504..97dacad5 100644 --- a/core/src/main/java/tech/kwik/core/send/GlobalPacketAssembler.java +++ b/core/src/main/java/tech/kwik/core/send/GlobalPacketAssembler.java @@ -28,9 +28,15 @@ import tech.kwik.core.impl.VersionHolder; import java.time.Instant; -import java.util.*; - -import static tech.kwik.core.common.EncryptionLevel.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import static tech.kwik.core.common.EncryptionLevel.Handshake; +import static tech.kwik.core.common.EncryptionLevel.Initial; +import static tech.kwik.core.common.EncryptionLevel.ZeroRTT; /** * Assembles QUIC packets for sending. diff --git a/core/src/main/java/tech/kwik/core/send/InitialPacketAssembler.java b/core/src/main/java/tech/kwik/core/send/InitialPacketAssembler.java index 27618f88..e247326a 100644 --- a/core/src/main/java/tech/kwik/core/send/InitialPacketAssembler.java +++ b/core/src/main/java/tech/kwik/core/send/InitialPacketAssembler.java @@ -20,8 +20,8 @@ import tech.kwik.core.ack.AckGenerator; import tech.kwik.core.common.EncryptionLevel; -import tech.kwik.core.frame.QuicFrame; import tech.kwik.core.impl.VersionHolder; +import tech.kwik.core.frame.QuicFrame; import tech.kwik.core.packet.InitialPacket; import tech.kwik.core.packet.QuicPacket; diff --git a/core/src/main/java/tech/kwik/core/send/SenderImpl.java b/core/src/main/java/tech/kwik/core/send/SenderImpl.java index d29ffb4f..8c8ef52e 100644 --- a/core/src/main/java/tech/kwik/core/send/SenderImpl.java +++ b/core/src/main/java/tech/kwik/core/send/SenderImpl.java @@ -49,7 +49,11 @@ import java.time.Clock; import java.time.Duration; import java.time.Instant; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Function; diff --git a/core/src/main/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilter.java b/core/src/main/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilter.java index 04a6eff2..2108b1b2 100644 --- a/core/src/main/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilter.java +++ b/core/src/main/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilter.java @@ -21,7 +21,11 @@ import tech.kwik.core.impl.TransportError; import tech.kwik.core.impl.Version; import tech.kwik.core.log.Logger; -import tech.kwik.core.packet.*; +import tech.kwik.core.packet.BaseDatagramFilter; +import tech.kwik.core.packet.DatagramFilter; +import tech.kwik.core.packet.InitialPacket; +import tech.kwik.core.packet.LongHeaderPacket; +import tech.kwik.core.packet.PacketMetaData; import java.nio.ByteBuffer; diff --git a/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionImpl.java b/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionImpl.java index 16b9f6a5..7c2e630c 100644 --- a/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionImpl.java +++ b/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionImpl.java @@ -23,7 +23,11 @@ import tech.kwik.agent15.TlsProtocolException; import tech.kwik.agent15.alert.MissingExtensionAlert; import tech.kwik.agent15.alert.NoApplicationProtocolAlert; -import tech.kwik.agent15.engine.*; +import tech.kwik.agent15.engine.ServerMessageSender; +import tech.kwik.agent15.engine.TlsEngine; +import tech.kwik.agent15.engine.TlsServerEngine; +import tech.kwik.agent15.engine.TlsServerEngineFactory; +import tech.kwik.agent15.engine.TlsStatusEventHandler; import tech.kwik.agent15.extension.ApplicationLayerProtocolNegotiationExtension; import tech.kwik.agent15.extension.Extension; import tech.kwik.agent15.handshake.*; @@ -34,13 +38,21 @@ import tech.kwik.core.common.EncryptionLevel; import tech.kwik.core.common.PnSpace; import tech.kwik.core.crypto.CryptoStream; -import tech.kwik.core.frame.*; +import tech.kwik.core.frame.CryptoFrame; +import tech.kwik.core.frame.HandshakeDoneFrame; +import tech.kwik.core.frame.NewTokenFrame; +import tech.kwik.core.frame.QuicFrame; +import tech.kwik.core.frame.RetireConnectionIdFrame; import tech.kwik.core.impl.*; import tech.kwik.core.log.LogProxy; import tech.kwik.core.log.Logger; import tech.kwik.core.packet.*; import tech.kwik.core.send.SenderImpl; -import tech.kwik.core.server.*; +import tech.kwik.core.server.ApplicationProtocolConnectionFactory; +import tech.kwik.core.server.ApplicationProtocolSettings; +import tech.kwik.core.server.ServerConnection; +import tech.kwik.core.server.ServerConnectionConfig; +import tech.kwik.core.server.ServerConnectionRegistry; import tech.kwik.core.stream.FlowControl; import tech.kwik.core.stream.StreamManager; import tech.kwik.core.tls.QuicTransportParametersExtension; @@ -49,6 +61,7 @@ import java.io.IOException; import java.net.DatagramSocket; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.security.SecureRandom; @@ -60,7 +73,9 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; -import static tech.kwik.core.QuicConstants.TransportErrorCode.*; +import static tech.kwik.core.QuicConstants.TransportErrorCode.INVALID_TOKEN; +import static tech.kwik.core.QuicConstants.TransportErrorCode.PROTOCOL_VIOLATION; +import static tech.kwik.core.QuicConstants.TransportErrorCode.TRANSPORT_PARAMETER_ERROR; import static tech.kwik.core.common.EncryptionLevel.Initial; import static tech.kwik.core.impl.QuicConnectionImpl.Status.Connected; import static tech.kwik.core.impl.QuicConnectionImpl.Status.Handshaking; diff --git a/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionRegistryImpl.java b/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionRegistryImpl.java index cac7bc9c..3e21d023 100644 --- a/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionRegistryImpl.java +++ b/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionRegistryImpl.java @@ -26,7 +26,11 @@ import java.net.InetSocketAddress; import java.security.SecureRandom; import java.time.Duration; -import java.util.*; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; diff --git a/core/src/main/java/tech/kwik/core/server/impl/ServerConnectorImpl.java b/core/src/main/java/tech/kwik/core/server/impl/ServerConnectorImpl.java index d9a43120..17f2a7b8 100644 --- a/core/src/main/java/tech/kwik/core/server/impl/ServerConnectorImpl.java +++ b/core/src/main/java/tech/kwik/core/server/impl/ServerConnectorImpl.java @@ -55,7 +55,11 @@ import java.security.spec.InvalidKeySpecException; import java.time.Duration; import java.time.Instant; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.*; import java.util.stream.Collectors; diff --git a/core/src/main/java/tech/kwik/core/stream/StreamManager.java b/core/src/main/java/tech/kwik/core/stream/StreamManager.java index 3b86257c..1c994e5f 100644 --- a/core/src/main/java/tech/kwik/core/stream/StreamManager.java +++ b/core/src/main/java/tech/kwik/core/stream/StreamManager.java @@ -27,7 +27,11 @@ import tech.kwik.core.log.Logger; import java.util.Map; -import java.util.concurrent.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Consumer; diff --git a/core/src/test/java/tech/kwik/core/StatisticsTest.java b/core/src/test/java/tech/kwik/core/StatisticsTest.java index daacf9ee..b3a1f197 100644 --- a/core/src/test/java/tech/kwik/core/StatisticsTest.java +++ b/core/src/test/java/tech/kwik/core/StatisticsTest.java @@ -18,8 +18,8 @@ */ package tech.kwik.core; -import org.junit.jupiter.api.Test; import tech.kwik.core.send.SendStatistics; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/core/src/test/java/tech/kwik/core/cc/CongestionControllerTest.java b/core/src/test/java/tech/kwik/core/cc/CongestionControllerTest.java index 6164f61e..fa43dd6c 100644 --- a/core/src/test/java/tech/kwik/core/cc/CongestionControllerTest.java +++ b/core/src/test/java/tech/kwik/core/cc/CongestionControllerTest.java @@ -18,14 +18,14 @@ */ package tech.kwik.core.cc; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import tech.kwik.core.impl.MockPacket; import tech.kwik.core.frame.AckFrame; import tech.kwik.core.frame.Padding; -import tech.kwik.core.impl.MockPacket; import tech.kwik.core.log.Logger; import tech.kwik.core.packet.PacketInfo; import tech.kwik.core.packet.QuicPacket; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.time.Instant; import java.util.List; diff --git a/core/src/test/java/tech/kwik/core/cc/NewRenoCongestionControllerTest.java b/core/src/test/java/tech/kwik/core/cc/NewRenoCongestionControllerTest.java index 0592701a..5222892c 100644 --- a/core/src/test/java/tech/kwik/core/cc/NewRenoCongestionControllerTest.java +++ b/core/src/test/java/tech/kwik/core/cc/NewRenoCongestionControllerTest.java @@ -18,14 +18,14 @@ */ package tech.kwik.core.cc; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import tech.kwik.core.common.EncryptionLevel; -import tech.kwik.core.frame.Padding; import tech.kwik.core.impl.MockPacket; +import tech.kwik.core.frame.Padding; import tech.kwik.core.log.NullLogger; import tech.kwik.core.packet.PacketInfo; import tech.kwik.core.packet.QuicPacket; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.time.Instant; import java.util.List; diff --git a/core/src/test/java/tech/kwik/core/cid/DestinationConnectionIdRegistryTest.java b/core/src/test/java/tech/kwik/core/cid/DestinationConnectionIdRegistryTest.java index e3cb5bff..67cf6285 100644 --- a/core/src/test/java/tech/kwik/core/cid/DestinationConnectionIdRegistryTest.java +++ b/core/src/test/java/tech/kwik/core/cid/DestinationConnectionIdRegistryTest.java @@ -18,9 +18,9 @@ */ package tech.kwik.core.cid; +import tech.kwik.core.log.Logger; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import tech.kwik.core.log.Logger; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/core/src/test/java/tech/kwik/core/crypto/ConnectionSecretsTest.java b/core/src/test/java/tech/kwik/core/crypto/ConnectionSecretsTest.java index 552fac03..74754d6d 100644 --- a/core/src/test/java/tech/kwik/core/crypto/ConnectionSecretsTest.java +++ b/core/src/test/java/tech/kwik/core/crypto/ConnectionSecretsTest.java @@ -18,12 +18,12 @@ */ package tech.kwik.core.crypto; -import org.junit.jupiter.api.Test; import tech.kwik.core.common.EncryptionLevel; import tech.kwik.core.impl.Role; import tech.kwik.core.impl.Version; import tech.kwik.core.impl.VersionHolder; import tech.kwik.core.log.Logger; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.ThrowableAssert.catchThrowable; diff --git a/core/src/test/java/tech/kwik/core/crypto/CryptoStreamTest.java b/core/src/test/java/tech/kwik/core/crypto/CryptoStreamTest.java index bbb81ece..301154aa 100644 --- a/core/src/test/java/tech/kwik/core/crypto/CryptoStreamTest.java +++ b/core/src/test/java/tech/kwik/core/crypto/CryptoStreamTest.java @@ -55,7 +55,9 @@ import java.util.function.Function; import java.util.stream.Collectors; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; import static tech.kwik.agent15.TlsConstants.HandshakeType.certificate_request; diff --git a/core/src/test/java/tech/kwik/core/frame/CryptoFrameTest.java b/core/src/test/java/tech/kwik/core/frame/CryptoFrameTest.java index 3854b85e..2250f8db 100644 --- a/core/src/test/java/tech/kwik/core/frame/CryptoFrameTest.java +++ b/core/src/test/java/tech/kwik/core/frame/CryptoFrameTest.java @@ -19,8 +19,8 @@ package tech.kwik.core.frame; -import org.junit.jupiter.api.Test; import tech.kwik.core.impl.Version; +import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/frame/NewConnectionIdFrameTest.java b/core/src/test/java/tech/kwik/core/frame/NewConnectionIdFrameTest.java index 7c3231fb..5ed58566 100644 --- a/core/src/test/java/tech/kwik/core/frame/NewConnectionIdFrameTest.java +++ b/core/src/test/java/tech/kwik/core/frame/NewConnectionIdFrameTest.java @@ -18,8 +18,8 @@ */ package tech.kwik.core.frame; -import org.junit.jupiter.api.Test; import tech.kwik.core.impl.Version; +import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/frame/PaddingTest.java b/core/src/test/java/tech/kwik/core/frame/PaddingTest.java index cc1f408d..d861be90 100644 --- a/core/src/test/java/tech/kwik/core/frame/PaddingTest.java +++ b/core/src/test/java/tech/kwik/core/frame/PaddingTest.java @@ -18,8 +18,8 @@ */ package tech.kwik.core.frame; -import org.junit.jupiter.api.Test; import tech.kwik.core.log.Logger; +import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/frame/RetireConnectionIdFrameTest.java b/core/src/test/java/tech/kwik/core/frame/RetireConnectionIdFrameTest.java index e3f016c9..73510007 100644 --- a/core/src/test/java/tech/kwik/core/frame/RetireConnectionIdFrameTest.java +++ b/core/src/test/java/tech/kwik/core/frame/RetireConnectionIdFrameTest.java @@ -18,8 +18,8 @@ */ package tech.kwik.core.frame; -import org.junit.jupiter.api.Test; import tech.kwik.core.impl.Version; +import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/frame/StopSendingFrameTest.java b/core/src/test/java/tech/kwik/core/frame/StopSendingFrameTest.java index facfc75c..6b7e70cc 100644 --- a/core/src/test/java/tech/kwik/core/frame/StopSendingFrameTest.java +++ b/core/src/test/java/tech/kwik/core/frame/StopSendingFrameTest.java @@ -18,8 +18,8 @@ */ package tech.kwik.core.frame; -import org.junit.jupiter.api.Test; import tech.kwik.core.impl.Version; +import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/frame/StreamDataBlockedFrameTest.java b/core/src/test/java/tech/kwik/core/frame/StreamDataBlockedFrameTest.java index 55571c21..faf4cf51 100644 --- a/core/src/test/java/tech/kwik/core/frame/StreamDataBlockedFrameTest.java +++ b/core/src/test/java/tech/kwik/core/frame/StreamDataBlockedFrameTest.java @@ -19,8 +19,8 @@ package tech.kwik.core.frame; -import org.junit.jupiter.api.Test; import tech.kwik.core.impl.Version; +import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/frame/StreamFrameTest.java b/core/src/test/java/tech/kwik/core/frame/StreamFrameTest.java index 8f7cce5b..04725da6 100644 --- a/core/src/test/java/tech/kwik/core/frame/StreamFrameTest.java +++ b/core/src/test/java/tech/kwik/core/frame/StreamFrameTest.java @@ -18,9 +18,9 @@ */ package tech.kwik.core.frame; +import tech.kwik.core.log.Logger; import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import tech.kwik.core.log.Logger; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/frame/StreamsBlockedFrameTest.java b/core/src/test/java/tech/kwik/core/frame/StreamsBlockedFrameTest.java index 087038bf..89249950 100644 --- a/core/src/test/java/tech/kwik/core/frame/StreamsBlockedFrameTest.java +++ b/core/src/test/java/tech/kwik/core/frame/StreamsBlockedFrameTest.java @@ -19,8 +19,8 @@ package tech.kwik.core.frame; -import org.junit.jupiter.api.Test; import tech.kwik.core.impl.Version; +import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/impl/EncryptionLevelTest.java b/core/src/test/java/tech/kwik/core/impl/EncryptionLevelTest.java index 95663ff4..6d12b313 100644 --- a/core/src/test/java/tech/kwik/core/impl/EncryptionLevelTest.java +++ b/core/src/test/java/tech/kwik/core/impl/EncryptionLevelTest.java @@ -18,11 +18,11 @@ */ package tech.kwik.core.impl; -import org.junit.jupiter.api.Test; import tech.kwik.core.common.EncryptionLevel; +import org.junit.jupiter.api.Test; -import static org.assertj.core.api.Assertions.assertThat; import static tech.kwik.core.common.EncryptionLevel.*; +import static org.assertj.core.api.Assertions.assertThat; class EncryptionLevelTest { diff --git a/core/src/test/java/tech/kwik/core/impl/IdleTimerTest.java b/core/src/test/java/tech/kwik/core/impl/IdleTimerTest.java index 21c9eb0f..63a78f43 100644 --- a/core/src/test/java/tech/kwik/core/impl/IdleTimerTest.java +++ b/core/src/test/java/tech/kwik/core/impl/IdleTimerTest.java @@ -18,16 +18,16 @@ */ package tech.kwik.core.impl; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import tech.kwik.core.frame.PingFrame; import tech.kwik.core.log.Logger; import tech.kwik.core.packet.ShortHeaderPacket; import tech.kwik.core.test.FieldSetter; import tech.kwik.core.test.TestClock; import tech.kwik.core.test.TestScheduledExecutor; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; import java.util.concurrent.ScheduledExecutorService; diff --git a/core/src/test/java/tech/kwik/core/impl/KeepAliveActorTest.java b/core/src/test/java/tech/kwik/core/impl/KeepAliveActorTest.java index 7c9bf71a..49fb852d 100644 --- a/core/src/test/java/tech/kwik/core/impl/KeepAliveActorTest.java +++ b/core/src/test/java/tech/kwik/core/impl/KeepAliveActorTest.java @@ -18,14 +18,14 @@ */ package tech.kwik.core.impl; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import tech.kwik.core.common.EncryptionLevel; import tech.kwik.core.frame.PingFrame; import tech.kwik.core.send.Sender; import tech.kwik.core.test.TestClock; import tech.kwik.core.test.TestScheduledExecutor; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.util.concurrent.ScheduledExecutorService; diff --git a/core/src/test/java/tech/kwik/core/impl/PacketMatcherByConnectionId.java b/core/src/test/java/tech/kwik/core/impl/PacketMatcherByConnectionId.java index 0978007f..9b7f9f24 100644 --- a/core/src/test/java/tech/kwik/core/impl/PacketMatcherByConnectionId.java +++ b/core/src/test/java/tech/kwik/core/impl/PacketMatcherByConnectionId.java @@ -18,9 +18,9 @@ */ package tech.kwik.core.impl; -import org.mockito.ArgumentMatcher; import tech.kwik.core.packet.QuicPacket; import tech.kwik.core.packet.ShortHeaderPacket; +import org.mockito.ArgumentMatcher; import java.util.Arrays; diff --git a/core/src/test/java/tech/kwik/core/impl/PacketMatcherByFrameClass.java b/core/src/test/java/tech/kwik/core/impl/PacketMatcherByFrameClass.java index e9df8027..92032856 100644 --- a/core/src/test/java/tech/kwik/core/impl/PacketMatcherByFrameClass.java +++ b/core/src/test/java/tech/kwik/core/impl/PacketMatcherByFrameClass.java @@ -18,8 +18,8 @@ */ package tech.kwik.core.impl; -import org.mockito.ArgumentMatcher; import tech.kwik.core.packet.QuicPacket; +import org.mockito.ArgumentMatcher; public class PacketMatcherByFrameClass implements ArgumentMatcher { diff --git a/core/src/test/java/tech/kwik/core/impl/PacketMatcherByPacketNumber.java b/core/src/test/java/tech/kwik/core/impl/PacketMatcherByPacketNumber.java index b19a102e..74e771d3 100644 --- a/core/src/test/java/tech/kwik/core/impl/PacketMatcherByPacketNumber.java +++ b/core/src/test/java/tech/kwik/core/impl/PacketMatcherByPacketNumber.java @@ -18,8 +18,8 @@ */ package tech.kwik.core.impl; -import org.mockito.ArgumentMatcher; import tech.kwik.core.packet.QuicPacket; +import org.mockito.ArgumentMatcher; public class PacketMatcherByPacketNumber implements ArgumentMatcher { diff --git a/core/src/test/java/tech/kwik/core/impl/PaddingTest.java b/core/src/test/java/tech/kwik/core/impl/PaddingTest.java index 049ab26c..7d636ba0 100644 --- a/core/src/test/java/tech/kwik/core/impl/PaddingTest.java +++ b/core/src/test/java/tech/kwik/core/impl/PaddingTest.java @@ -18,10 +18,10 @@ */ package tech.kwik.core.impl; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import tech.kwik.core.frame.Padding; import tech.kwik.core.log.Logger; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/impl/PnSpaceTest.java b/core/src/test/java/tech/kwik/core/impl/PnSpaceTest.java index 172d84c1..c673a0ed 100644 --- a/core/src/test/java/tech/kwik/core/impl/PnSpaceTest.java +++ b/core/src/test/java/tech/kwik/core/impl/PnSpaceTest.java @@ -18,9 +18,11 @@ */ package tech.kwik.core.impl; +import tech.kwik.core.common.PnSpace; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; -import tech.kwik.core.common.PnSpace; + +import static org.assertj.core.api.Assertions.assertThat; class PnSpaceTest { diff --git a/core/src/test/java/tech/kwik/core/impl/QuicClientConnectionImplTest.java b/core/src/test/java/tech/kwik/core/impl/QuicClientConnectionImplTest.java index 880c2888..35eff672 100644 --- a/core/src/test/java/tech/kwik/core/impl/QuicClientConnectionImplTest.java +++ b/core/src/test/java/tech/kwik/core/impl/QuicClientConnectionImplTest.java @@ -41,7 +41,11 @@ import tech.kwik.core.packet.*; import tech.kwik.core.send.SenderImpl; import tech.kwik.core.stream.StreamManager; -import tech.kwik.core.test.*; +import tech.kwik.core.test.ByteUtils; +import tech.kwik.core.test.FieldReader; +import tech.kwik.core.test.FieldSetter; +import tech.kwik.core.test.TestClock; +import tech.kwik.core.test.TestScheduledExecutor; import java.io.IOException; import java.net.Inet4Address; diff --git a/core/src/test/java/tech/kwik/core/impl/QuicSessionTicketImplTest.java b/core/src/test/java/tech/kwik/core/impl/QuicSessionTicketImplTest.java index 23d0f825..d2eefa61 100644 --- a/core/src/test/java/tech/kwik/core/impl/QuicSessionTicketImplTest.java +++ b/core/src/test/java/tech/kwik/core/impl/QuicSessionTicketImplTest.java @@ -18,10 +18,10 @@ */ package tech.kwik.core.impl; -import org.junit.jupiter.api.Test; import tech.kwik.agent15.NewSessionTicket; import tech.kwik.agent15.TlsConstants; import tech.kwik.agent15.handshake.NewSessionTicketMessage; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/core/src/test/java/tech/kwik/core/impl/TestUtils.java b/core/src/test/java/tech/kwik/core/impl/TestUtils.java index b40b77c0..bf6ba87c 100644 --- a/core/src/test/java/tech/kwik/core/impl/TestUtils.java +++ b/core/src/test/java/tech/kwik/core/impl/TestUtils.java @@ -27,11 +27,11 @@ import javax.crypto.Cipher; +import static tech.kwik.core.impl.Version.IETF_draft_29; +import static tech.kwik.core.impl.Version.QUIC_version_1; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static tech.kwik.core.impl.Version.IETF_draft_29; -import static tech.kwik.core.impl.Version.QUIC_version_1; public class TestUtils { diff --git a/core/src/test/java/tech/kwik/core/packet/ClientRolePacketParserTest.java b/core/src/test/java/tech/kwik/core/packet/ClientRolePacketParserTest.java index 5c478813..87e4ca5e 100644 --- a/core/src/test/java/tech/kwik/core/packet/ClientRolePacketParserTest.java +++ b/core/src/test/java/tech/kwik/core/packet/ClientRolePacketParserTest.java @@ -18,8 +18,6 @@ */ package tech.kwik.core.packet; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import tech.kwik.core.crypto.ConnectionSecrets; import tech.kwik.core.impl.InvalidPacketException; import tech.kwik.core.impl.Role; @@ -27,6 +25,8 @@ import tech.kwik.core.impl.VersionHolder; import tech.kwik.core.log.Logger; import tech.kwik.core.test.ByteUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/packet/HandshakePacketTest.java b/core/src/test/java/tech/kwik/core/packet/HandshakePacketTest.java index c55febc2..3d20e6ef 100644 --- a/core/src/test/java/tech/kwik/core/packet/HandshakePacketTest.java +++ b/core/src/test/java/tech/kwik/core/packet/HandshakePacketTest.java @@ -26,7 +26,11 @@ import tech.kwik.core.crypto.Aead; import tech.kwik.core.crypto.ConnectionSecrets; import tech.kwik.core.frame.*; -import tech.kwik.core.impl.*; +import tech.kwik.core.impl.InvalidPacketException; +import tech.kwik.core.impl.Role; +import tech.kwik.core.impl.TestUtils; +import tech.kwik.core.impl.Version; +import tech.kwik.core.impl.VersionHolder; import tech.kwik.core.log.Logger; import tech.kwik.core.test.ByteUtils; diff --git a/core/src/test/java/tech/kwik/core/packet/LongHeaderPacketTest.java b/core/src/test/java/tech/kwik/core/packet/LongHeaderPacketTest.java index 32ff531a..ab286063 100644 --- a/core/src/test/java/tech/kwik/core/packet/LongHeaderPacketTest.java +++ b/core/src/test/java/tech/kwik/core/packet/LongHeaderPacketTest.java @@ -18,8 +18,8 @@ */ package tech.kwik.core.packet; -import org.junit.jupiter.api.Test; import tech.kwik.core.impl.Version; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/core/src/test/java/tech/kwik/core/packet/RetryPacketTest.java b/core/src/test/java/tech/kwik/core/packet/RetryPacketTest.java index 69f7b8f0..cb155fa7 100644 --- a/core/src/test/java/tech/kwik/core/packet/RetryPacketTest.java +++ b/core/src/test/java/tech/kwik/core/packet/RetryPacketTest.java @@ -18,11 +18,11 @@ */ package tech.kwik.core.packet; -import org.junit.jupiter.api.Test; import tech.kwik.core.impl.InvalidPacketException; import tech.kwik.core.impl.Version; import tech.kwik.core.log.Logger; import tech.kwik.core.test.ByteUtils; +import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/packet/ServerRolePacketParserTest.java b/core/src/test/java/tech/kwik/core/packet/ServerRolePacketParserTest.java index 639743f7..e310d7ad 100644 --- a/core/src/test/java/tech/kwik/core/packet/ServerRolePacketParserTest.java +++ b/core/src/test/java/tech/kwik/core/packet/ServerRolePacketParserTest.java @@ -18,14 +18,14 @@ */ package tech.kwik.core.packet; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import tech.kwik.core.crypto.ConnectionSecrets; -import tech.kwik.core.crypto.MissingKeysException; import tech.kwik.core.impl.Role; import tech.kwik.core.impl.Version; import tech.kwik.core.impl.VersionHolder; +import tech.kwik.core.crypto.ConnectionSecrets; +import tech.kwik.core.crypto.MissingKeysException; import tech.kwik.core.log.Logger; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/packet/ShortHeaderPacketTest.java b/core/src/test/java/tech/kwik/core/packet/ShortHeaderPacketTest.java index a8ea2d45..fa9e4796 100644 --- a/core/src/test/java/tech/kwik/core/packet/ShortHeaderPacketTest.java +++ b/core/src/test/java/tech/kwik/core/packet/ShortHeaderPacketTest.java @@ -18,12 +18,12 @@ */ package tech.kwik.core.packet; -import org.junit.jupiter.api.Test; +import tech.kwik.core.impl.TestUtils; +import tech.kwik.core.impl.Version; import tech.kwik.core.crypto.Aead; import tech.kwik.core.frame.PingFrame; import tech.kwik.core.frame.StreamFrame; -import tech.kwik.core.impl.TestUtils; -import tech.kwik.core.impl.Version; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/core/src/test/java/tech/kwik/core/packet/VersionNegotiationPacketTest.java b/core/src/test/java/tech/kwik/core/packet/VersionNegotiationPacketTest.java index ef467389..3fbf617a 100644 --- a/core/src/test/java/tech/kwik/core/packet/VersionNegotiationPacketTest.java +++ b/core/src/test/java/tech/kwik/core/packet/VersionNegotiationPacketTest.java @@ -18,12 +18,12 @@ */ package tech.kwik.core.packet; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import tech.kwik.core.impl.InvalidPacketException; import tech.kwik.core.impl.Version; import tech.kwik.core.log.Logger; import tech.kwik.core.test.ByteUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; import java.util.stream.Collectors; diff --git a/core/src/test/java/tech/kwik/core/packet/ZeroRttPacketTest.java b/core/src/test/java/tech/kwik/core/packet/ZeroRttPacketTest.java index 58694c34..d5404b96 100644 --- a/core/src/test/java/tech/kwik/core/packet/ZeroRttPacketTest.java +++ b/core/src/test/java/tech/kwik/core/packet/ZeroRttPacketTest.java @@ -18,11 +18,11 @@ */ package tech.kwik.core.packet; -import org.junit.jupiter.api.Test; -import tech.kwik.core.frame.QuicFrame; -import tech.kwik.core.frame.StreamFrame; import tech.kwik.core.impl.TestUtils; import tech.kwik.core.impl.Version; +import tech.kwik.core.frame.QuicFrame; +import tech.kwik.core.frame.StreamFrame; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/core/src/test/java/tech/kwik/core/receive/ReceiverTest.java b/core/src/test/java/tech/kwik/core/receive/ReceiverTest.java index 9b2ddf68..a9a5bfd7 100644 --- a/core/src/test/java/tech/kwik/core/receive/ReceiverTest.java +++ b/core/src/test/java/tech/kwik/core/receive/ReceiverTest.java @@ -18,10 +18,10 @@ */ package tech.kwik.core.receive; +import tech.kwik.core.log.Logger; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import tech.kwik.core.log.Logger; import java.net.DatagramPacket; import java.net.DatagramSocket; diff --git a/core/src/test/java/tech/kwik/core/recovery/RecoveryTests.java b/core/src/test/java/tech/kwik/core/recovery/RecoveryTests.java index 0df37720..15843f57 100644 --- a/core/src/test/java/tech/kwik/core/recovery/RecoveryTests.java +++ b/core/src/test/java/tech/kwik/core/recovery/RecoveryTests.java @@ -18,11 +18,15 @@ */ package tech.kwik.core.recovery; +import tech.kwik.core.impl.Version; import tech.kwik.core.frame.CryptoFrame; import tech.kwik.core.frame.MaxDataFrame; import tech.kwik.core.frame.QuicFrame; -import tech.kwik.core.impl.Version; -import tech.kwik.core.packet.*; +import tech.kwik.core.packet.HandshakePacket; +import tech.kwik.core.packet.InitialPacket; +import tech.kwik.core.packet.LongHeaderPacket; +import tech.kwik.core.packet.QuicPacket; +import tech.kwik.core.packet.ShortHeaderPacket; import tech.kwik.core.test.FieldSetter; import java.time.Instant; diff --git a/core/src/test/java/tech/kwik/core/send/AbstractSenderTest.java b/core/src/test/java/tech/kwik/core/send/AbstractSenderTest.java index d9a949b3..88faf70d 100644 --- a/core/src/test/java/tech/kwik/core/send/AbstractSenderTest.java +++ b/core/src/test/java/tech/kwik/core/send/AbstractSenderTest.java @@ -18,10 +18,10 @@ */ package tech.kwik.core.send; -import org.junit.jupiter.api.BeforeEach; import tech.kwik.core.common.EncryptionLevel; -import tech.kwik.core.crypto.Aead; import tech.kwik.core.impl.TestUtils; +import tech.kwik.core.crypto.Aead; +import org.junit.jupiter.api.BeforeEach; public class AbstractSenderTest { diff --git a/core/src/test/java/tech/kwik/core/send/PacketAssemblerTest.java b/core/src/test/java/tech/kwik/core/send/PacketAssemblerTest.java index 715b12a5..9a551a72 100644 --- a/core/src/test/java/tech/kwik/core/send/PacketAssemblerTest.java +++ b/core/src/test/java/tech/kwik/core/send/PacketAssemblerTest.java @@ -42,7 +42,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.data.Percentage.withPercentage; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; class PacketAssemblerTest extends AbstractSenderTest { diff --git a/core/src/test/java/tech/kwik/core/send/SendRequestQueueTest.java b/core/src/test/java/tech/kwik/core/send/SendRequestQueueTest.java index 314d13ca..1b42e4d4 100644 --- a/core/src/test/java/tech/kwik/core/send/SendRequestQueueTest.java +++ b/core/src/test/java/tech/kwik/core/send/SendRequestQueueTest.java @@ -18,10 +18,14 @@ */ package tech.kwik.core.send; +import tech.kwik.core.frame.CryptoFrame; +import tech.kwik.core.frame.DatagramFrame; +import tech.kwik.core.frame.PathResponseFrame; +import tech.kwik.core.frame.QuicFrame; +import tech.kwik.core.frame.StreamFrame; +import tech.kwik.core.impl.Version; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import tech.kwik.core.frame.*; -import tech.kwik.core.impl.Version; import java.time.Duration; import java.time.Instant; diff --git a/core/src/test/java/tech/kwik/core/server/impl/ApplicationProtocolRegistryTest.java b/core/src/test/java/tech/kwik/core/server/impl/ApplicationProtocolRegistryTest.java index 1457bee0..ab01c041 100644 --- a/core/src/test/java/tech/kwik/core/server/impl/ApplicationProtocolRegistryTest.java +++ b/core/src/test/java/tech/kwik/core/server/impl/ApplicationProtocolRegistryTest.java @@ -18,9 +18,9 @@ */ package tech.kwik.core.server.impl; -import org.junit.jupiter.api.Test; import tech.kwik.core.impl.QuicConnectionImpl; import tech.kwik.core.server.ApplicationProtocolConnection; +import org.junit.jupiter.api.Test; import java.util.List; import java.util.Optional; diff --git a/core/src/test/java/tech/kwik/core/server/impl/ClientAddressFilterTest.java b/core/src/test/java/tech/kwik/core/server/impl/ClientAddressFilterTest.java index 1600320c..5c73b793 100644 --- a/core/src/test/java/tech/kwik/core/server/impl/ClientAddressFilterTest.java +++ b/core/src/test/java/tech/kwik/core/server/impl/ClientAddressFilterTest.java @@ -28,7 +28,9 @@ import java.time.Instant; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; class ClientAddressFilterTest { diff --git a/core/src/test/java/tech/kwik/core/server/impl/ClientInitialScidFilterTest.java b/core/src/test/java/tech/kwik/core/server/impl/ClientInitialScidFilterTest.java index d6ba58fb..86a778d8 100644 --- a/core/src/test/java/tech/kwik/core/server/impl/ClientInitialScidFilterTest.java +++ b/core/src/test/java/tech/kwik/core/server/impl/ClientInitialScidFilterTest.java @@ -26,7 +26,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; class ClientInitialScidFilterTest { diff --git a/core/src/test/java/tech/kwik/core/server/impl/InitialPacketFilterProxyTest.java b/core/src/test/java/tech/kwik/core/server/impl/InitialPacketFilterProxyTest.java index 43ade0b4..b5c53131 100644 --- a/core/src/test/java/tech/kwik/core/server/impl/InitialPacketFilterProxyTest.java +++ b/core/src/test/java/tech/kwik/core/server/impl/InitialPacketFilterProxyTest.java @@ -18,10 +18,10 @@ */ package tech.kwik.core.server.impl; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import tech.kwik.core.impl.Version; import tech.kwik.core.log.LogProxy; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; import java.time.Instant; diff --git a/core/src/test/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilterTest.java b/core/src/test/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilterTest.java index ffa56284..74fc6cf9 100644 --- a/core/src/test/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilterTest.java +++ b/core/src/test/java/tech/kwik/core/server/impl/InitialPacketMinimumSizeFilterTest.java @@ -28,7 +28,9 @@ import java.nio.ByteBuffer; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; class InitialPacketMinimumSizeFilterTest { diff --git a/core/src/test/java/tech/kwik/core/server/impl/ServerConnectionImplTest.java b/core/src/test/java/tech/kwik/core/server/impl/ServerConnectionImplTest.java index 26c118f8..f55e4237 100644 --- a/core/src/test/java/tech/kwik/core/server/impl/ServerConnectionImplTest.java +++ b/core/src/test/java/tech/kwik/core/server/impl/ServerConnectionImplTest.java @@ -47,7 +47,11 @@ import tech.kwik.core.frame.FrameProcessor; import tech.kwik.core.impl.*; import tech.kwik.core.log.Logger; -import tech.kwik.core.packet.*; +import tech.kwik.core.packet.HandshakePacket; +import tech.kwik.core.packet.InitialPacket; +import tech.kwik.core.packet.PacketMetaData; +import tech.kwik.core.packet.QuicPacket; +import tech.kwik.core.packet.RetryPacket; import tech.kwik.core.send.SenderImpl; import tech.kwik.core.server.ApplicationProtocolConnection; import tech.kwik.core.server.ApplicationProtocolConnectionFactory; diff --git a/core/src/test/java/tech/kwik/core/server/impl/ServerConnectorImplTest.java b/core/src/test/java/tech/kwik/core/server/impl/ServerConnectorImplTest.java index 276099b2..61b16586 100644 --- a/core/src/test/java/tech/kwik/core/server/impl/ServerConnectorImplTest.java +++ b/core/src/test/java/tech/kwik/core/server/impl/ServerConnectorImplTest.java @@ -41,7 +41,11 @@ import tech.kwik.core.server.ApplicationProtocolConnectionFactory; import tech.kwik.core.server.ServerConnectionFactory; import tech.kwik.core.server.ServerConnectionRegistry; -import tech.kwik.core.test.*; +import tech.kwik.core.test.ByteUtils; +import tech.kwik.core.test.FieldReader; +import tech.kwik.core.test.FieldSetter; +import tech.kwik.core.test.TestClock; +import tech.kwik.core.test.TestScheduledExecutor; import java.io.InputStream; import java.net.DatagramPacket; diff --git a/core/src/test/java/tech/kwik/core/stream/EarlyDataStreamTest.java b/core/src/test/java/tech/kwik/core/stream/EarlyDataStreamTest.java index 64a10f0a..9fbf4a90 100644 --- a/core/src/test/java/tech/kwik/core/stream/EarlyDataStreamTest.java +++ b/core/src/test/java/tech/kwik/core/stream/EarlyDataStreamTest.java @@ -18,17 +18,17 @@ */ package tech.kwik.core.stream; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; import tech.kwik.core.common.EncryptionLevel; -import tech.kwik.core.frame.QuicFrame; -import tech.kwik.core.frame.StreamFrame; import tech.kwik.core.impl.QuicClientConnectionImpl; import tech.kwik.core.impl.Role; import tech.kwik.core.impl.Version; +import tech.kwik.core.frame.QuicFrame; +import tech.kwik.core.frame.StreamFrame; import tech.kwik.core.log.Logger; import tech.kwik.core.log.NullLogger; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import java.io.IOException; import java.nio.ByteBuffer; diff --git a/core/src/test/java/tech/kwik/core/stream/FlowControlTest.java b/core/src/test/java/tech/kwik/core/stream/FlowControlTest.java index 96567d85..813afcaf 100644 --- a/core/src/test/java/tech/kwik/core/stream/FlowControlTest.java +++ b/core/src/test/java/tech/kwik/core/stream/FlowControlTest.java @@ -18,15 +18,15 @@ */ package tech.kwik.core.stream; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import tech.kwik.core.QuicStream; -import tech.kwik.core.frame.MaxDataFrame; -import tech.kwik.core.frame.MaxStreamDataFrame; import tech.kwik.core.impl.QuicConnectionImpl; import tech.kwik.core.impl.Role; import tech.kwik.core.impl.TransportError; import tech.kwik.core.impl.TransportParameters; +import tech.kwik.core.frame.MaxDataFrame; +import tech.kwik.core.frame.MaxStreamDataFrame; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; diff --git a/core/src/test/java/tech/kwik/core/stream/QuicStreamImplTest.java b/core/src/test/java/tech/kwik/core/stream/QuicStreamImplTest.java index e328c9dc..8147e14d 100644 --- a/core/src/test/java/tech/kwik/core/stream/QuicStreamImplTest.java +++ b/core/src/test/java/tech/kwik/core/stream/QuicStreamImplTest.java @@ -24,7 +24,11 @@ import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import tech.kwik.core.common.EncryptionLevel; -import tech.kwik.core.frame.*; +import tech.kwik.core.frame.MaxStreamDataFrame; +import tech.kwik.core.frame.QuicFrame; +import tech.kwik.core.frame.ResetStreamFrame; +import tech.kwik.core.frame.StopSendingFrame; +import tech.kwik.core.frame.StreamFrame; import tech.kwik.core.generic.IntegerTooLargeException; import tech.kwik.core.generic.InvalidIntegerEncodingException; import tech.kwik.core.impl.QuicConnectionImpl; diff --git a/core/src/test/java/tech/kwik/core/stream/RetransmitBufferTest.java b/core/src/test/java/tech/kwik/core/stream/RetransmitBufferTest.java index 75934992..5102bdb8 100644 --- a/core/src/test/java/tech/kwik/core/stream/RetransmitBufferTest.java +++ b/core/src/test/java/tech/kwik/core/stream/RetransmitBufferTest.java @@ -19,9 +19,9 @@ package tech.kwik.core.stream; +import tech.kwik.core.frame.StreamFrame; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import tech.kwik.core.frame.StreamFrame; import static org.assertj.core.api.Assertions.assertThat; diff --git a/core/src/test/java/tech/kwik/core/stream/StreamManagerTest.java b/core/src/test/java/tech/kwik/core/stream/StreamManagerTest.java index 412791a0..4b0c2b3d 100644 --- a/core/src/test/java/tech/kwik/core/stream/StreamManagerTest.java +++ b/core/src/test/java/tech/kwik/core/stream/StreamManagerTest.java @@ -18,13 +18,14 @@ */ package tech.kwik.core.stream; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; import tech.kwik.core.ConnectionConfig; import tech.kwik.core.QuicStream; import tech.kwik.core.common.EncryptionLevel; -import tech.kwik.core.frame.*; +import tech.kwik.core.frame.MaxDataFrame; +import tech.kwik.core.frame.MaxStreamsFrame; +import tech.kwik.core.frame.QuicFrame; +import tech.kwik.core.frame.ResetStreamFrame; +import tech.kwik.core.frame.StreamFrame; import tech.kwik.core.impl.QuicConnectionImpl; import tech.kwik.core.impl.Role; import tech.kwik.core.impl.TransportError; @@ -33,6 +34,9 @@ import tech.kwik.core.test.FieldReader; import tech.kwik.core.test.TestClock; import tech.kwik.core.test.TestScheduledExecutor; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import java.util.ArrayList; import java.util.HashMap; @@ -44,11 +48,15 @@ import java.util.function.Consumer; import java.util.function.Function; -import static org.assertj.core.api.Assertions.*; +import static tech.kwik.core.QuicConstants.TransportErrorCode.FINAL_SIZE_ERROR; +import static tech.kwik.core.QuicConstants.TransportErrorCode.FLOW_CONTROL_ERROR; +import static tech.kwik.core.QuicConstants.TransportErrorCode.STREAM_LIMIT_ERROR; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.*; -import static tech.kwik.core.QuicConstants.TransportErrorCode.*; class StreamManagerTest { diff --git a/core/src/test/java/tech/kwik/core/test/TestClock.java b/core/src/test/java/tech/kwik/core/test/TestClock.java index b0e7bdd8..630a484c 100644 --- a/core/src/test/java/tech/kwik/core/test/TestClock.java +++ b/core/src/test/java/tech/kwik/core/test/TestClock.java @@ -18,7 +18,11 @@ */ package tech.kwik.core.test; -import java.time.*; +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZoneOffset; import java.time.temporal.TemporalAmount; import java.util.ArrayList; import java.util.List; diff --git a/core/src/test/java/tech/kwik/core/tls/ClientHelloBuilder.java b/core/src/test/java/tech/kwik/core/tls/ClientHelloBuilder.java index 1e0451c8..0149abe0 100644 --- a/core/src/test/java/tech/kwik/core/tls/ClientHelloBuilder.java +++ b/core/src/test/java/tech/kwik/core/tls/ClientHelloBuilder.java @@ -18,13 +18,13 @@ */ package tech.kwik.core.tls; -import org.junit.jupiter.api.Test; +import tech.kwik.core.test.ByteUtils; import tech.kwik.agent15.ProtectionKeysType; import tech.kwik.agent15.TlsConstants; import tech.kwik.agent15.engine.MessageProcessor; import tech.kwik.agent15.engine.TlsMessageParser; import tech.kwik.agent15.handshake.HandshakeMessage; -import tech.kwik.core.test.ByteUtils; +import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; import java.util.ArrayList; diff --git a/h09/src/main/java/tech/kwik/h09/io/LimitExceededException.java b/h09/src/main/java/tech/kwik/h09/io/LimitExceededException.java index e05f669f..84cd4422 100644 --- a/h09/src/main/java/tech/kwik/h09/io/LimitExceededException.java +++ b/h09/src/main/java/tech/kwik/h09/io/LimitExceededException.java @@ -1,9 +1,28 @@ +/* + * Copyright © 2019, 2020, 2021, 2022, 2023, 2024, 2025 Peter Doornbosch + * + * This file is part of Kwik, an implementation of the QUIC protocol in Java. + * + * Kwik is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Kwik is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ package tech.kwik.h09.io; import java.io.IOException; public class LimitExceededException extends IOException { + public LimitExceededException(long limit) { super("Limit of " + limit + " bytes is exceeded"); } -} \ No newline at end of file +} diff --git a/h09/src/main/java/tech/kwik/h09/io/LimitedInputStream.java b/h09/src/main/java/tech/kwik/h09/io/LimitedInputStream.java index 8f38c77d..a1c05920 100644 --- a/h09/src/main/java/tech/kwik/h09/io/LimitedInputStream.java +++ b/h09/src/main/java/tech/kwik/h09/io/LimitedInputStream.java @@ -42,7 +42,8 @@ public int read() throws IOException { int read = super.read(); bytesRead++; return read; - } else { + } + else { throw new LimitExceededException(limit); } diff --git a/h09/src/main/java/tech/kwik/h09/server/Http09Connection.java b/h09/src/main/java/tech/kwik/h09/server/Http09Connection.java index 29e4d340..c6604eac 100644 --- a/h09/src/main/java/tech/kwik/h09/server/Http09Connection.java +++ b/h09/src/main/java/tech/kwik/h09/server/Http09Connection.java @@ -18,7 +18,11 @@ */ package tech.kwik.h09.server; -import tech.kwik.core.*; +import tech.kwik.core.KwikVersion; +import tech.kwik.core.QuicConnection; +import tech.kwik.core.QuicConstants; +import tech.kwik.core.QuicStream; +import tech.kwik.core.StreamClosedException; import tech.kwik.core.server.ApplicationProtocolConnection; import tech.kwik.h09.io.LimitExceededException; import tech.kwik.h09.io.LimitedInputStream; diff --git a/h09/src/test/java/tech/kwik/h09/server/Http09ConnectionTest.java b/h09/src/test/java/tech/kwik/h09/server/Http09ConnectionTest.java index 594ef6ee..35603c72 100644 --- a/h09/src/test/java/tech/kwik/h09/server/Http09ConnectionTest.java +++ b/h09/src/test/java/tech/kwik/h09/server/Http09ConnectionTest.java @@ -18,12 +18,16 @@ */ package tech.kwik.h09.server; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import tech.kwik.core.QuicConnection; import tech.kwik.core.QuicStream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/interop/src/main/java/tech/kwik/interop/InteropClient.java b/interop/src/main/java/tech/kwik/interop/InteropClient.java index 5f2432fd..b4ef7aa8 100644 --- a/interop/src/main/java/tech/kwik/interop/InteropClient.java +++ b/interop/src/main/java/tech/kwik/interop/InteropClient.java @@ -22,11 +22,11 @@ import tech.kwik.core.QuicConnection; import tech.kwik.core.QuicSessionTicket; import tech.kwik.core.QuicStream; +import tech.kwik.h09.client.Http09Client; import tech.kwik.core.impl.QuicClientConnectionImpl; import tech.kwik.core.log.FileLogger; import tech.kwik.core.log.Logger; import tech.kwik.core.log.NullLogger; -import tech.kwik.h09.client.Http09Client; import java.io.File; import java.io.FileOutputStream; diff --git a/interop/src/main/java/tech/kwik/interop/InteropServer.java b/interop/src/main/java/tech/kwik/interop/InteropServer.java index cf074691..559d72eb 100644 --- a/interop/src/main/java/tech/kwik/interop/InteropServer.java +++ b/interop/src/main/java/tech/kwik/interop/InteropServer.java @@ -18,7 +18,11 @@ */ package tech.kwik.interop; -import org.apache.commons.cli.*; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; import tech.kwik.core.KwikVersion; import tech.kwik.core.QuicConnection; import tech.kwik.core.log.FileLogger; diff --git a/qlog/src/main/java/tech/kwik/qlog/ConnectionQLog.java b/qlog/src/main/java/tech/kwik/qlog/ConnectionQLog.java index 9472dc1c..2c120a29 100644 --- a/qlog/src/main/java/tech/kwik/qlog/ConnectionQLog.java +++ b/qlog/src/main/java/tech/kwik/qlog/ConnectionQLog.java @@ -26,7 +26,11 @@ import tech.kwik.core.util.Bytes; import tech.kwik.qlog.event.*; -import java.io.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; import java.time.Duration; import java.time.Instant; import java.util.Map; diff --git a/qlog/src/main/java/tech/kwik/qlog/QLogFrontEnd.java b/qlog/src/main/java/tech/kwik/qlog/QLogFrontEnd.java index 1411377b..bc3c93c1 100644 --- a/qlog/src/main/java/tech/kwik/qlog/QLogFrontEnd.java +++ b/qlog/src/main/java/tech/kwik/qlog/QLogFrontEnd.java @@ -24,7 +24,11 @@ import java.io.File; import java.time.Instant; -import java.util.*; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Queue; +import java.util.Random; /** * Entrypoint of the QLog module. Collects qlog events and processes them asynchronously. diff --git a/qlog/src/main/java/tech/kwik/qlog/event/PacketSentEvent.java b/qlog/src/main/java/tech/kwik/qlog/event/PacketSentEvent.java index be909d80..df47b6b5 100644 --- a/qlog/src/main/java/tech/kwik/qlog/event/PacketSentEvent.java +++ b/qlog/src/main/java/tech/kwik/qlog/event/PacketSentEvent.java @@ -1,3 +1,21 @@ +/* + * Copyright © 2020, 2021, 2022, 2023, 2024, 2025 Peter Doornbosch + * + * This file is part of Kwik, an implementation of the QUIC protocol in Java. + * + * Kwik is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Kwik is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ package tech.kwik.qlog.event; import tech.kwik.core.packet.QuicPacket; @@ -14,4 +32,4 @@ public void accept(QLogEventProcessor processor) { processor.process(this); } -} \ No newline at end of file +} From 8624faafc6b4646a2736fa54dd45b363d5416073 Mon Sep 17 00:00:00 2001 From: Mechite Date: Tue, 13 Jan 2026 04:24:38 +0000 Subject: [PATCH 04/17] Make `#getInitialClientAddress` return `#getAddress` Related-to: 6f2c8ce22f29752fb034f3346587039990824e45 Signed-off-by: Mahied Maruf --- .../java/tech/kwik/core/server/impl/ServerConnectionImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionImpl.java b/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionImpl.java index 444ce4a4..81b946c8 100644 --- a/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionImpl.java +++ b/core/src/main/java/tech/kwik/core/server/impl/ServerConnectionImpl.java @@ -671,8 +671,8 @@ protected void validateTransportParameters(TransportParameters transportParamete } @Override - public InetSocketAddress getInitialClientAddress() { - return initialClientAddress; + public InetAddress getInitialClientAddress() { + return initialClientAddress.getAddress(); } @Override From f798f84c371f348a4f1a5c80951b2c5eb3f913af Mon Sep 17 00:00:00 2001 From: Mechite Date: Tue, 13 Jan 2026 04:30:07 +0000 Subject: [PATCH 05/17] Make `QuicConnectionImpl#read/writeListener` private Update all usages to use the accessor methods. Signed-off-by: Mahied Maruf --- .../java/tech/kwik/core/impl/QuicConnectionImpl.java | 4 ++-- .../java/tech/kwik/core/stream/ReceiveBufferImpl.java | 9 ++++----- core/src/main/java/tech/kwik/core/stream/SendBuffer.java | 4 +++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/tech/kwik/core/impl/QuicConnectionImpl.java b/core/src/main/java/tech/kwik/core/impl/QuicConnectionImpl.java index 4cc1cb35..0bf87468 100644 --- a/core/src/main/java/tech/kwik/core/impl/QuicConnectionImpl.java +++ b/core/src/main/java/tech/kwik/core/impl/QuicConnectionImpl.java @@ -142,8 +142,8 @@ protected enum ErrorType { private volatile ConnectionCloseFrame lastConnectionCloseFrameSent; private final ScheduledExecutorService scheduler; private ConnectionListener connectionListener; - public StreamReadListener readListener; - public StreamWriteListener writeListener; + private StreamReadListener readListener; + private StreamWriteListener writeListener; protected final ExecutorService callbackThread; // https://datatracker.ietf.org/doc/html/rfc9221 Datagram Extension diff --git a/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java b/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java index 49799b65..e9a5cd5e 100644 --- a/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java +++ b/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java @@ -74,17 +74,16 @@ public ReceiveBufferImpl(QuicStreamImpl stream, int maxCombinedFrameSize) { } private void notifyWriter(boolean force) { - if (stream == null || stream.connection == null || stream.connection.readListener == null) return; + if (stream == null || stream.connection == null || stream.connection.getStreamReadListener() == null) return; if (stream.isInputClosed()) return; long avail = bytesAvailable(); if (force || avail != lastAvailData) { lastAvailData = avail; ListenerThreadPool.execute(stream, () -> { - if (!stream.isInputClosed()) { - stream.connection.readListener.read(stream, avail); - } - }); + if (stream.isInputClosed()) return; + stream.connection.getStreamReadListener().read(stream, avail); + }); } } diff --git a/core/src/main/java/tech/kwik/core/stream/SendBuffer.java b/core/src/main/java/tech/kwik/core/stream/SendBuffer.java index ef1ecf0e..9c2d8b43 100644 --- a/core/src/main/java/tech/kwik/core/stream/SendBuffer.java +++ b/core/src/main/java/tech/kwik/core/stream/SendBuffer.java @@ -66,7 +66,9 @@ public SendBuffer(QuicStreamImpl stream, Integer sendBufferSize) { } public void notifyCanWrite(boolean force) { - var l = (stream != null && stream.connection != null) ? stream.connection.writeListener : null; // use o listener que você já tem + var l = (stream != null && stream.connection != null) + ? stream.connection.getStreamWriteListener() : + null; if (l == null) return; else if (stream.isOutputClosed()) return; From 53bcb8af3c3419fea830ed675a684a6664a2b9dd Mon Sep 17 00:00:00 2001 From: Mechite Date: Tue, 13 Jan 2026 04:32:01 +0000 Subject: [PATCH 06/17] Stylistic changes in `SendBuffer` - Explicit type over `var` - Variable name `listener` instead of `l` - Reduce one level of nesting Signed-off-by: Mahied Maruf --- .../main/java/tech/kwik/core/stream/SendBuffer.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/tech/kwik/core/stream/SendBuffer.java b/core/src/main/java/tech/kwik/core/stream/SendBuffer.java index 9c2d8b43..ed035c46 100644 --- a/core/src/main/java/tech/kwik/core/stream/SendBuffer.java +++ b/core/src/main/java/tech/kwik/core/stream/SendBuffer.java @@ -18,6 +18,7 @@ */ package tech.kwik.core.stream; +import tech.kwik.core.StreamWriteListener; import tech.kwik.core.frame.StreamFrame; import tech.kwik.core.impl.Version; @@ -66,10 +67,10 @@ public SendBuffer(QuicStreamImpl stream, Integer sendBufferSize) { } public void notifyCanWrite(boolean force) { - var l = (stream != null && stream.connection != null) + StreamWriteListener listener = (stream != null && stream.connection != null) ? stream.connection.getStreamWriteListener() : null; - if (l == null) return; + if (listener == null) return; else if (stream.isOutputClosed()) return; int avail = getAvailableBytes(); @@ -80,10 +81,9 @@ public void notifyCanWrite(boolean force) { lastReportedAvail = report; lastReportedWritable = canWrite; ListenerThreadPool.execute(stream, () -> { - if (!stream.isOutputClosed()) { - l.write(stream, report); - } - }); + if (stream.isOutputClosed()) return; + listener.write(stream, report); + }); } } From 482e51dba92349389dbd1befc137ea5397ac9b3c Mon Sep 17 00:00:00 2001 From: Mechite Date: Tue, 13 Jan 2026 04:33:39 +0000 Subject: [PATCH 07/17] Remove seemingly unused `java.naming` JNDI dependency This was added to the h09 module and seems to not be necessary. Signed-off-by: Mahied Maruf --- h09/src/main/java/module-info.java | 1 - 1 file changed, 1 deletion(-) diff --git a/h09/src/main/java/module-info.java b/h09/src/main/java/module-info.java index 514441c0..62cc0626 100644 --- a/h09/src/main/java/module-info.java +++ b/h09/src/main/java/module-info.java @@ -1,7 +1,6 @@ module tech.kwik.h09 { requires tech.kwik.core; requires java.net.http; - requires java.naming; exports tech.kwik.h09.client; } \ No newline at end of file From 753579562cba5e36a197a6a9ae4784e488db58fe Mon Sep 17 00:00:00 2001 From: Mechite Date: Tue, 13 Jan 2026 04:41:13 +0000 Subject: [PATCH 08/17] Add basic javadoc to new `interface`s Signed-off-by: Mahied Maruf --- .../main/java/tech/kwik/core/StreamReadListener.java | 9 +++++++++ .../main/java/tech/kwik/core/StreamWriteListener.java | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/core/src/main/java/tech/kwik/core/StreamReadListener.java b/core/src/main/java/tech/kwik/core/StreamReadListener.java index 995c4f28..779fec4f 100644 --- a/core/src/main/java/tech/kwik/core/StreamReadListener.java +++ b/core/src/main/java/tech/kwik/core/StreamReadListener.java @@ -18,6 +18,15 @@ */ package tech.kwik.core; +/** + * Listener that is notified when data is read from a {@link QuicStream}. + */ public interface StreamReadListener { + + /** + * Called when bytes are read from a stream. + * @param stream the stream that data was read from + * @param amount the number of bytes read + */ void read(QuicStream stream, long amount); } diff --git a/core/src/main/java/tech/kwik/core/StreamWriteListener.java b/core/src/main/java/tech/kwik/core/StreamWriteListener.java index 9e324f05..11cd2aa0 100644 --- a/core/src/main/java/tech/kwik/core/StreamWriteListener.java +++ b/core/src/main/java/tech/kwik/core/StreamWriteListener.java @@ -18,6 +18,16 @@ */ package tech.kwik.core; +/** + * Listener that is notified when data is written to a {@link QuicStream}. + */ +@FunctionalInterface public interface StreamWriteListener { + + /** + * Called when bytes are written to a stream. + * @param stream the stream that data was written to + * @param amount the number of bytes written + */ void write(QuicStream stream, long amount); } From da77ca6bdc6ba234246c34a455111ed3a7dd9804 Mon Sep 17 00:00:00 2001 From: Mechite Date: Tue, 13 Jan 2026 04:44:03 +0000 Subject: [PATCH 09/17] Revert wildcard import change & import `.DataBlockedFrame` Signed-off-by: Mahied Maruf --- .../java/tech/kwik/core/stream/StreamOutputStreamImpl.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java b/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java index 1a36dc35..a9f193a8 100644 --- a/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java +++ b/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java @@ -19,7 +19,11 @@ package tech.kwik.core.stream; import tech.kwik.core.common.EncryptionLevel; -import tech.kwik.core.frame.*; +import tech.kwik.core.frame.QuicFrame; +import tech.kwik.core.frame.ResetStreamFrame; +import tech.kwik.core.frame.StreamDataBlockedFrame; +import tech.kwik.core.frame.DataBlockedFrame; +import tech.kwik.core.frame.StreamFrame; import tech.kwik.core.log.Logger; import java.io.IOException; From 96876d70038de4b7f4809dedbfca27e248135c49 Mon Sep 17 00:00:00 2001 From: Mechite Date: Tue, 13 Jan 2026 04:53:56 +0000 Subject: [PATCH 10/17] Make `ListenerThreadPool` not use static initialization This moves the pool to the `QuicStreamImpl`, but still continues to be a package-private implementation detail. Signed-off-by: Mahied Maruf --- .../kwik/core/stream/ListenerThreadPool.java | 45 ++++++++----------- .../tech/kwik/core/stream/QuicStreamImpl.java | 2 + .../kwik/core/stream/ReceiveBufferImpl.java | 2 +- .../tech/kwik/core/stream/SendBuffer.java | 2 +- 4 files changed, 23 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java b/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java index 5d05fa65..1119a2f3 100644 --- a/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java +++ b/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java @@ -2,35 +2,30 @@ import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -final class ListenerThreadPool { +import static java.util.concurrent.TimeUnit.SECONDS; - // Static initializers +final class ListenerThreadPool implements AutoCloseable { - private static final List pending = new ArrayList<>(); - private static final ThreadPoolExecutor executor; + private final List pending; + private final ExecutorService executor; - static { - executor = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new ThreadFactory() { - @Override - public Thread newThread(Runnable runnable) { - Thread thread = new Thread(runnable, "kwik-listener"); - thread.setDaemon(true); + ListenerThreadPool() { + this.pending = new ArrayList<>(); + this.executor = new ThreadPoolExecutor(1, 1, 1, + SECONDS, new LinkedBlockingQueue<>(), runnable -> { + Thread thread = new Thread(runnable, "kwik-listener"); + thread.setDaemon(true); - return thread; - } - }); + return thread; + }); } - public static void execute(QuicStreamImpl stream, Runnable runnable) { - if (pending.contains(stream)) { - return; - } - + void execute(QuicStreamImpl stream, Runnable runnable) { + if (pending.contains(stream)) return; executor.execute(() -> { try { runnable.run(); @@ -39,11 +34,9 @@ public static void execute(QuicStreamImpl stream, Runnable runnable) { } }); } - - // Object - - private ListenerThreadPool() { - throw new UnsupportedOperationException("this class cannot be instantiated"); + + @Override + public void close() { + //todo } - } diff --git a/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java b/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java index 3e1c162d..29d4fd68 100644 --- a/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java +++ b/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java @@ -39,6 +39,7 @@ public class QuicStreamImpl implements QuicStream { protected final int streamId; protected final Role role; protected final QuicConnectionImpl connection; + final ListenerThreadPool listenerPool; private final StreamManager streamManager; protected final Logger log; private final StreamInputStream inputStream; @@ -83,6 +84,7 @@ public QuicStreamImpl(Version quicVersion, int streamId, Role role, QuicConnecti } stateLock = new ReentrantLock(); + listenerPool = new ListenerThreadPool(); } private long determineInitialReceiveBufferSize() { diff --git a/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java b/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java index e9a5cd5e..3bf429e3 100644 --- a/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java +++ b/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java @@ -80,7 +80,7 @@ private void notifyWriter(boolean force) { long avail = bytesAvailable(); if (force || avail != lastAvailData) { lastAvailData = avail; - ListenerThreadPool.execute(stream, () -> { + this.stream.listenerPool.execute(stream, () -> { if (stream.isInputClosed()) return; stream.connection.getStreamReadListener().read(stream, avail); }); diff --git a/core/src/main/java/tech/kwik/core/stream/SendBuffer.java b/core/src/main/java/tech/kwik/core/stream/SendBuffer.java index ed035c46..2a61aadb 100644 --- a/core/src/main/java/tech/kwik/core/stream/SendBuffer.java +++ b/core/src/main/java/tech/kwik/core/stream/SendBuffer.java @@ -80,7 +80,7 @@ public void notifyCanWrite(boolean force) { if (force || report != lastReportedAvail || canWrite != lastReportedWritable) { lastReportedAvail = report; lastReportedWritable = canWrite; - ListenerThreadPool.execute(stream, () -> { + this.stream.listenerPool.execute(stream, () -> { if (stream.isOutputClosed()) return; listener.write(stream, report); }); From 9fe86994ca7e24917aac9528c9c94df8eb1252fd Mon Sep 17 00:00:00 2001 From: Mechite Date: Tue, 13 Jan 2026 04:59:47 +0000 Subject: [PATCH 11/17] Make `ListenerThreadPool` & `QuicStream` implement `AutoCloseable` This change copies the OpenJDK 19+ default close method in `ListenerThreadPool` (for support of older versions). The `QuicStream#close` method here does not follow the existing TODO comment, only closes the new `ListenerThreadPool`. Signed-off-by: Mahied Maruf --- .../main/java/tech/kwik/core/QuicStream.java | 2 +- .../kwik/core/stream/ListenerThreadPool.java | 28 +++++++++++++++++-- .../tech/kwik/core/stream/QuicStreamImpl.java | 12 ++++++-- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/tech/kwik/core/QuicStream.java b/core/src/main/java/tech/kwik/core/QuicStream.java index a888644d..1e6cbc52 100644 --- a/core/src/main/java/tech/kwik/core/QuicStream.java +++ b/core/src/main/java/tech/kwik/core/QuicStream.java @@ -29,7 +29,7 @@ * unidirectional or bidirectional." * */ -public interface QuicStream { +public interface QuicStream extends AutoCloseable { /** * Returns the input stream for reading data sent by the peer. diff --git a/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java b/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java index 1119a2f3..2c45d598 100644 --- a/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java +++ b/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java @@ -6,6 +6,8 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; +import static java.lang.Thread.currentThread; +import static java.util.concurrent.TimeUnit.DAYS; import static java.util.concurrent.TimeUnit.SECONDS; final class ListenerThreadPool implements AutoCloseable { @@ -35,8 +37,30 @@ void execute(QuicStreamImpl stream, Runnable runnable) { }); } + /** + * Implementation of {@link AutoCloseable#close()} that performs an + * orderly shutdown of {@link #executor}. + * + * @implNote This is a clone of OpenJDK 19+ default close method + * available directly on the newer {@code ExecutorService} interface. + */ @Override public void close() { - //todo - } + boolean terminated = this.executor.isTerminated(); + if (terminated) return; + + this.executor.shutdown(); + boolean interrupted = false; + while (!terminated) { + try { + terminated = this.executor.awaitTermination(1L, DAYS); + } catch (InterruptedException e) { + if (interrupted) continue; + this.executor.shutdownNow(); + interrupted = true; + } + } + if (!interrupted) return; + currentThread().interrupt(); + } } diff --git a/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java b/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java index 29d4fd68..3af4ce3f 100644 --- a/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java +++ b/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java @@ -205,8 +205,16 @@ protected StreamOutputStream createStreamOutputStream(Integer sendBufferSize, Fl long terminateStream(long errorCode, long finalSize) throws TransportError { return inputStream.terminate(errorCode, finalSize); } - - // TODO: QuicStream should have a close method that closes both input and output stream and releases all resources and marks itself as terminated. + + @Override + public void close() { + // TODO: QuicStream should have a close method that closes both input + // and output stream and releases all resources and marks itself as + // terminated. + + // currently only closing the listener thread pool + this.listenerPool.close(); + } /** * Resets the output stream so data can again be send from the start of the stream (offset 0). Note that in such From 97974055367f58c13900a1f8781a4d5ca689e4f8 Mon Sep 17 00:00:00 2001 From: Mechite Date: Tue, 13 Jan 2026 05:07:07 +0000 Subject: [PATCH 12/17] Use `Executors#newSingleThreadExecutor` instead of `ThreadPoolExecutor` This is equivalent, available since JDK 1.5, and simpler. Signed-off-by: Mahied Maruf --- .../java/tech/kwik/core/stream/ListenerThreadPool.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java b/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java index 2c45d598..7339c28b 100644 --- a/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java +++ b/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java @@ -3,12 +3,10 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; import static java.lang.Thread.currentThread; +import static java.util.concurrent.Executors.newSingleThreadExecutor; import static java.util.concurrent.TimeUnit.DAYS; -import static java.util.concurrent.TimeUnit.SECONDS; final class ListenerThreadPool implements AutoCloseable { @@ -17,11 +15,9 @@ final class ListenerThreadPool implements AutoCloseable { ListenerThreadPool() { this.pending = new ArrayList<>(); - this.executor = new ThreadPoolExecutor(1, 1, 1, - SECONDS, new LinkedBlockingQueue<>(), runnable -> { + this.executor = newSingleThreadExecutor(runnable -> { Thread thread = new Thread(runnable, "kwik-listener"); thread.setDaemon(true); - return thread; }); } From 6121bb2a2f56cefc1ee736ecb6d030a52216cbd2 Mon Sep 17 00:00:00 2001 From: Mechite Date: Tue, 13 Jan 2026 05:13:07 +0000 Subject: [PATCH 13/17] Remove `#pending` list from `ListenerThreadPool` This does not appear to have been ever written to, only ever read from. It was also never guarded against multi-threaded access. This patch also makes `ListenerThreadPool implements Executor` as a result of the stream no longer being tracked. Signed-off-by: Mahied Maruf --- .../kwik/core/stream/ListenerThreadPool.java | 25 ++++++------------- .../kwik/core/stream/ReceiveBufferImpl.java | 2 +- .../tech/kwik/core/stream/SendBuffer.java | 2 +- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java b/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java index 7339c28b..f692f535 100644 --- a/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java +++ b/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java @@ -1,38 +1,29 @@ package tech.kwik.core.stream; -import java.util.ArrayList; -import java.util.List; +import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import static java.lang.Thread.currentThread; import static java.util.concurrent.Executors.newSingleThreadExecutor; import static java.util.concurrent.TimeUnit.DAYS; -final class ListenerThreadPool implements AutoCloseable { +final class ListenerThreadPool implements Executor, AutoCloseable { - private final List pending; private final ExecutorService executor; ListenerThreadPool() { - this.pending = new ArrayList<>(); this.executor = newSingleThreadExecutor(runnable -> { Thread thread = new Thread(runnable, "kwik-listener"); thread.setDaemon(true); return thread; }); } - - void execute(QuicStreamImpl stream, Runnable runnable) { - if (pending.contains(stream)) return; - executor.execute(() -> { - try { - runnable.run(); - } finally { - pending.remove(stream); - } - }); - } - + + @Override + public void execute(Runnable command) { + this.executor.execute(command); + } + /** * Implementation of {@link AutoCloseable#close()} that performs an * orderly shutdown of {@link #executor}. diff --git a/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java b/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java index 3bf429e3..02f818b7 100644 --- a/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java +++ b/core/src/main/java/tech/kwik/core/stream/ReceiveBufferImpl.java @@ -80,7 +80,7 @@ private void notifyWriter(boolean force) { long avail = bytesAvailable(); if (force || avail != lastAvailData) { lastAvailData = avail; - this.stream.listenerPool.execute(stream, () -> { + this.stream.listenerPool.execute(() -> { if (stream.isInputClosed()) return; stream.connection.getStreamReadListener().read(stream, avail); }); diff --git a/core/src/main/java/tech/kwik/core/stream/SendBuffer.java b/core/src/main/java/tech/kwik/core/stream/SendBuffer.java index 2a61aadb..34534625 100644 --- a/core/src/main/java/tech/kwik/core/stream/SendBuffer.java +++ b/core/src/main/java/tech/kwik/core/stream/SendBuffer.java @@ -80,7 +80,7 @@ public void notifyCanWrite(boolean force) { if (force || report != lastReportedAvail || canWrite != lastReportedWritable) { lastReportedAvail = report; lastReportedWritable = canWrite; - this.stream.listenerPool.execute(stream, () -> { + this.stream.listenerPool.execute(() -> { if (stream.isOutputClosed()) return; listener.write(stream, report); }); From 3cc09d6616545e0b7e4a0998a71f53632c622074 Mon Sep 17 00:00:00 2001 From: Mechite Date: Tue, 13 Jan 2026 05:18:20 +0000 Subject: [PATCH 14/17] Use package-private accessor for `SendBuffer` & mark field `private` Signed-off-by: Mahied Maruf --- .../main/java/tech/kwik/core/stream/QuicStreamImpl.java | 2 +- .../tech/kwik/core/stream/StreamOutputStreamImpl.java | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java b/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java index 3af4ce3f..88f22c66 100644 --- a/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java +++ b/core/src/main/java/tech/kwik/core/stream/QuicStreamImpl.java @@ -77,7 +77,7 @@ public QuicStreamImpl(Version quicVersion, int streamId, Role role, QuicConnecti if (isBidirectional() || isUnidirectional() && isSelfInitiated()) { outputStream = createStreamOutputStream(sendBufferSize, flowController); - ((StreamOutputStreamImpl) outputStream).sendBuffer.notifyCanWrite(true); + ((StreamOutputStreamImpl) outputStream).getSendBuffer().notifyCanWrite(true); } else { outputStream = new NullStreamOutputStream(); diff --git a/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java b/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java index a9f193a8..434d1519 100644 --- a/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java +++ b/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java @@ -41,7 +41,7 @@ class StreamOutputStreamImpl extends StreamOutputStream implements FlowControlUp private final QuicStreamImpl quicStream; private final Object lock = new Object(); - public final SendBuffer sendBuffer; + private final SendBuffer sendBuffer; private final Logger log; private final int maxBufferSize; private final RetransmitBuffer retransmitBuffer; @@ -264,7 +264,11 @@ private void retransmitStreamFrame(QuicFrame frame) { protected EncryptionLevel getEncryptionLevel() { return App; } - + + SendBuffer getSendBuffer() { + return sendBuffer; + } + // Very confusing name: this has nothing to do with resetting the stream as the reset method does! protected void resetOutputStream() { closed = false; From f054b15e40e5700065c5a551278100af63edea56 Mon Sep 17 00:00:00 2001 From: Mechite Date: Tue, 13 Jan 2026 05:18:50 +0000 Subject: [PATCH 15/17] Remove unused mutex field Signed-off-by: Mahied Maruf --- .../main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java b/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java index 434d1519..3a1226b6 100644 --- a/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java +++ b/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java @@ -39,7 +39,6 @@ class StreamOutputStreamImpl extends StreamOutputStream implements FlowControlUp private static final int MIN_FRAME_SIZE = 1 + 8 + 8 + 2 + 1; private final QuicStreamImpl quicStream; - private final Object lock = new Object(); private final SendBuffer sendBuffer; private final Logger log; From a8462f939bc63e6484e32ae0b620affa1e01ac9d Mon Sep 17 00:00:00 2001 From: Mechite Date: Tue, 13 Jan 2026 05:20:03 +0000 Subject: [PATCH 16/17] Simplify an assertion grep of `== true` and `== false` in the project returns no other results, so this is the only one. Signed-off-by: Mahied Maruf --- .../main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java b/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java index 3a1226b6..ee867ffb 100644 --- a/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java +++ b/core/src/main/java/tech/kwik/core/stream/StreamOutputStreamImpl.java @@ -305,7 +305,7 @@ private void discardAllData() { } private QuicFrame createResetFrame(int maxFrameSize) { - assert (reset == true); + assert reset; return new ResetStreamFrame(quicStream.streamId, resetErrorCode, currentOffset); } From 442a91c76b72a43b34f7691e5978a0dcfc108cce Mon Sep 17 00:00:00 2001 From: Mechite Date: Tue, 13 Jan 2026 05:33:33 +0000 Subject: [PATCH 17/17] Add virtual thread support This merges two files as-is from the related PR. It then uses the new `VirtualExecutor` system where the single-thread executor was previously being used as part of these async changes. Related-to: #74 Co-authored-by: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Signed-off-by: Mahied Maruf --- .../core/concurrent/DaemonThreadFactory.java | 44 ++++++++++++++-- .../kwik/core/concurrent/VirtualExecutor.java | 51 +++++++++++++++++++ .../kwik/core/stream/ListenerThreadPool.java | 13 ++++- 3 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 core/src/main/java/tech/kwik/core/concurrent/VirtualExecutor.java diff --git a/core/src/main/java/tech/kwik/core/concurrent/DaemonThreadFactory.java b/core/src/main/java/tech/kwik/core/concurrent/DaemonThreadFactory.java index bc10b816..352e47c4 100644 --- a/core/src/main/java/tech/kwik/core/concurrent/DaemonThreadFactory.java +++ b/core/src/main/java/tech/kwik/core/concurrent/DaemonThreadFactory.java @@ -18,27 +18,63 @@ */ package tech.kwik.core.concurrent; - +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; /** - * Creates daemon threads. Java's default thread factory used in executors creates non-daemon threads that - * prevent JVM from shutting down. + * Creates daemon threads. Java's default thread factory used in executors creates non-daemon + * threads that prevent JVM from shutting down. */ public class DaemonThreadFactory implements ThreadFactory { private final String threadBaseName; private final AtomicInteger threadNumber = new AtomicInteger(1); + private ThreadFactory virtualFactory; public DaemonThreadFactory(String threadBaseName) { this.threadBaseName = threadBaseName; + + if (Runtime.version().feature() >= 24) { + try { + var lookup = MethodHandles.lookup(); + var builderClass = Class.forName("java.lang.Thread$Builder$OfVirtual"); + // public static Builder.OfVirtual ofVirtual() + var ofVirtualHandle = + lookup.findStatic(Thread.class, "ofVirtual", MethodType.methodType(builderClass)); + + // 2. public Thread.Builder name(String prefix, long start) + var nameHandle = + lookup.findVirtual( + builderClass, + "name", + MethodType.methodType(builderClass, String.class, long.class)); + + // 3. Invoke Thread.ofVirtual().name(threadBaseName, 0) + var namedBuilder = nameHandle.invoke(ofVirtualHandle.invoke(), threadBaseName, 0L); + + // 4. public ThreadFactory factory() + var factoryHandle = + lookup.findVirtual(builderClass, "factory", MethodType.methodType(ThreadFactory.class)); + + // 5. Invoke namedBuilder.factory() + this.virtualFactory = (ThreadFactory) factoryHandle.invoke(namedBuilder); + } catch (Throwable e) { + // impossible + } + } } @Override public Thread newThread(Runnable runnable) { + + if (virtualFactory != null) { + return virtualFactory.newThread(runnable); + } + Thread thread = new Thread(runnable, threadBaseName + "-" + threadNumber.getAndIncrement()); thread.setDaemon(true); return thread; } -} +} \ No newline at end of file diff --git a/core/src/main/java/tech/kwik/core/concurrent/VirtualExecutor.java b/core/src/main/java/tech/kwik/core/concurrent/VirtualExecutor.java new file mode 100644 index 00000000..bee64b95 --- /dev/null +++ b/core/src/main/java/tech/kwik/core/concurrent/VirtualExecutor.java @@ -0,0 +1,51 @@ +package tech.kwik.core.concurrent; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; + +/** + * Utility class to reflectively invoke the Executors.newThreadPerTaskExecutor static method using + * the Method Handles API. + */ +public class VirtualExecutor { + + private static final boolean SUPPORTED = Runtime.version().feature() >= 24; + + private static MethodHandle handle; + + static { + try { + handle = + MethodHandles.publicLookup() + .findStatic( + Executors.class, + "newThreadPerTaskExecutor", + MethodType.methodType(ExecutorService.class, ThreadFactory.class)); + } catch (Exception __) { + // failing is of no consequence + } + } + + /** Returns true if virtual threads are supported in this JVM */ + public static boolean supported() { + return SUPPORTED; + } + + /** + * Reflectively creates a virtual thread executor + * + * @param name the name of the threads + * @return A new ExecutorService instance backed by virtual threads. + */ + public static ExecutorService createExecutor(String name) { + try { + return (ExecutorService) handle.invoke(new DaemonThreadFactory(name)); + } catch (Throwable e) { + throw new UnsupportedOperationException("this jvm doesn't support virtual threads"); + } + } +} \ No newline at end of file diff --git a/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java b/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java index f692f535..2abf4c65 100644 --- a/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java +++ b/core/src/main/java/tech/kwik/core/stream/ListenerThreadPool.java @@ -1,5 +1,7 @@ package tech.kwik.core.stream; +import tech.kwik.core.concurrent.VirtualExecutor; + import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; @@ -8,15 +10,22 @@ import static java.util.concurrent.TimeUnit.DAYS; final class ListenerThreadPool implements Executor, AutoCloseable { - + private final ExecutorService executor; + private final boolean virtual; ListenerThreadPool() { + if (VirtualExecutor.supported()) { + this.executor = VirtualExecutor.createExecutor("kwik-listener"); + this.virtual = true; + return; + } this.executor = newSingleThreadExecutor(runnable -> { Thread thread = new Thread(runnable, "kwik-listener"); thread.setDaemon(true); return thread; }); + this.virtual = false; } @Override @@ -33,6 +42,8 @@ public void execute(Runnable command) { */ @Override public void close() { + if (this.virtual) return; + boolean terminated = this.executor.isTerminated(); if (terminated) return;