Issue #6728 - QUIC and HTTP/3
- QPACK exceptions now use long instead of int, to be consistent with other error codes. - Fixed ManagedSelector to count down the stop latches in finally blocks, so that they are always counted down even in case of exceptions. - Improved exception handling in case of closes. Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
parent
8e81c80e1e
commit
c879358777
|
@ -86,7 +86,7 @@ public abstract class BodyParser
|
|||
}
|
||||
}
|
||||
|
||||
protected void notifyStreamFailure(long streamId, int error, Throwable failure)
|
||||
protected void notifyStreamFailure(long streamId, long error, Throwable failure)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
@ -13,23 +13,21 @@
|
|||
|
||||
package org.eclipse.jetty.http3.qpack;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class QpackException extends Exception
|
||||
{
|
||||
public static final int QPACK_DECOMPRESSION_FAILED = 0x200;
|
||||
public static final int QPACK_ENCODER_STREAM_ERROR = 0x201;
|
||||
public static final int QPACK_DECODER_STREAM_ERROR = 0x202;
|
||||
public static final int H3_GENERAL_PROTOCOL_ERROR = 0x0101;
|
||||
public static final long QPACK_DECOMPRESSION_FAILED = 0x200;
|
||||
public static final long QPACK_ENCODER_STREAM_ERROR = 0x201;
|
||||
public static final long QPACK_DECODER_STREAM_ERROR = 0x202;
|
||||
public static final long H3_GENERAL_PROTOCOL_ERROR = 0x0101;
|
||||
private final long _errorCode;
|
||||
|
||||
private final int _errorCode;
|
||||
|
||||
QpackException(int errorCode, String messageFormat, Throwable cause)
|
||||
QpackException(long errorCode, String messageFormat, Throwable cause)
|
||||
{
|
||||
super(messageFormat, cause);
|
||||
_errorCode = errorCode;
|
||||
}
|
||||
|
||||
public int getErrorCode()
|
||||
public long getErrorCode()
|
||||
{
|
||||
return _errorCode;
|
||||
}
|
||||
|
@ -43,12 +41,12 @@ public abstract class QpackException extends Exception
|
|||
*/
|
||||
public static class StreamException extends QpackException
|
||||
{
|
||||
public StreamException(int errorCode, String messageFormat)
|
||||
public StreamException(long errorCode, String messageFormat)
|
||||
{
|
||||
this(errorCode, messageFormat, null);
|
||||
}
|
||||
|
||||
public StreamException(int errorCode, String messageFormat, Throwable cause)
|
||||
public StreamException(long errorCode, String messageFormat, Throwable cause)
|
||||
{
|
||||
super(errorCode, messageFormat, cause);
|
||||
}
|
||||
|
@ -61,12 +59,12 @@ public abstract class QpackException extends Exception
|
|||
*/
|
||||
public static class SessionException extends QpackException
|
||||
{
|
||||
public SessionException(int errorCode, String message)
|
||||
public SessionException(long errorCode, String message)
|
||||
{
|
||||
this(errorCode, message, null);
|
||||
}
|
||||
|
||||
public SessionException(int errorCode, String message, Throwable cause)
|
||||
public SessionException(long errorCode, String message, Throwable cause)
|
||||
{
|
||||
super(errorCode, message, cause);
|
||||
}
|
||||
|
|
|
@ -36,6 +36,11 @@
|
|||
<artifactId>jetty-alpn-java-server</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jmx</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-server</artifactId>
|
||||
|
|
|
@ -13,8 +13,10 @@
|
|||
|
||||
package org.eclipse.jetty.http3.tests;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.management.MBeanServer;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic;
|
||||
|
@ -29,6 +31,7 @@ import org.eclipse.jetty.http3.client.http.ClientConnectionFactoryOverHTTP3;
|
|||
import org.eclipse.jetty.http3.server.HTTP3ServerConnectionFactory;
|
||||
import org.eclipse.jetty.http3.server.HTTP3ServerConnector;
|
||||
import org.eclipse.jetty.http3.server.RawHTTP3ServerConnectionFactory;
|
||||
import org.eclipse.jetty.jmx.MBeanContainer;
|
||||
import org.eclipse.jetty.server.ConnectionFactory;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
|
@ -79,6 +82,8 @@ public class AbstractClientServerTest
|
|||
server = new Server(serverThreads);
|
||||
connector = new HTTP3ServerConnector(server, sslContextFactory, serverConnectionFactory);
|
||||
server.addConnector(connector);
|
||||
MBeanContainer mbeanContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
|
||||
server.addBean(mbeanContainer);
|
||||
}
|
||||
|
||||
protected void startClient() throws Exception
|
||||
|
@ -88,6 +93,9 @@ public class AbstractClientServerTest
|
|||
QueuedThreadPool clientThreads = new QueuedThreadPool();
|
||||
clientThreads.setName("client");
|
||||
httpClient.setExecutor(clientThreads);
|
||||
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||
MBeanContainer mbeanContainer = new MBeanContainer(mbeanServer);
|
||||
httpClient.addBean(mbeanContainer);
|
||||
httpClient.start();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ package org.eclipse.jetty.io;
|
|||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.nio.channels.CancelledKeyException;
|
||||
import java.nio.channels.ClosedSelectorException;
|
||||
|
|
|
@ -171,7 +171,18 @@ public abstract class QuicConnection extends AbstractConnection
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("closing connection {}", this);
|
||||
// Propagate the close inward to the protocol-specific session.
|
||||
sessions.values().forEach(session -> session.inwardClose(QuicErrorCode.NO_ERROR.code(), "stop"));
|
||||
for (QuicSession session : sessions.values())
|
||||
{
|
||||
try
|
||||
{
|
||||
session.inwardClose(QuicErrorCode.NO_ERROR.code(), "stop");
|
||||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
if (LOG.isTraceEnabled())
|
||||
LOG.trace("could not close {}", session, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -219,12 +219,6 @@ public abstract class QuicSession extends ContainerLifeCycle
|
|||
return flushed;
|
||||
}
|
||||
|
||||
public void flushFinished(long streamId) throws IOException
|
||||
{
|
||||
quicheConnection.feedFinForStream(streamId);
|
||||
flush();
|
||||
}
|
||||
|
||||
public boolean isFinished(long streamId)
|
||||
{
|
||||
return quicheConnection.isStreamFinished(streamId);
|
||||
|
@ -397,7 +391,6 @@ public abstract class QuicSession extends ContainerLifeCycle
|
|||
public void inwardClose(long error, String reason)
|
||||
{
|
||||
protocolSession.inwardClose(error, reason);
|
||||
flush();
|
||||
}
|
||||
|
||||
public void outwardClose(long error, String reason)
|
||||
|
|
|
@ -70,12 +70,14 @@ public interface LibQuiche extends Library
|
|||
// The minimum length of Initial packets sent by a client.
|
||||
int QUICHE_MIN_CLIENT_INITIAL_LEN = 1200;
|
||||
|
||||
interface quiche_cc_algorithm {
|
||||
interface quiche_cc_algorithm
|
||||
{
|
||||
int QUICHE_CC_RENO = 0,
|
||||
QUICHE_CC_CUBIC = 1;
|
||||
QUICHE_CC_CUBIC = 1;
|
||||
}
|
||||
|
||||
interface quiche_error {
|
||||
interface quiche_error
|
||||
{
|
||||
// There is no more work to do.
|
||||
long QUICHE_ERR_DONE = -1,
|
||||
|
||||
|
@ -236,13 +238,15 @@ public interface LibQuiche extends Library
|
|||
public byte dummy;
|
||||
}
|
||||
|
||||
@Structure.FieldOrder({"recv", "sent", "lost", "retrans", "rtt", "cwnd", "sent_bytes", "recv_bytes", "lost_bytes",
|
||||
"stream_retrans_bytes", "pmtu", "delivery_rate", "peer_max_idle_timeout",
|
||||
"peer_max_udp_payload_size", "peer_initial_max_data", "peer_initial_max_stream_data_bidi_local",
|
||||
"peer_initial_max_stream_data_bidi_remote", "peer_initial_max_stream_data_uni",
|
||||
"peer_initial_max_streams_bidi", "peer_initial_max_streams_uni", "peer_ack_delay_exponent",
|
||||
"peer_max_ack_delay", "peer_disable_active_migration", "peer_active_conn_id_limit",
|
||||
"peer_max_datagram_frame_size"})
|
||||
@Structure.FieldOrder({
|
||||
"recv", "sent", "lost", "retrans", "rtt", "cwnd", "sent_bytes", "recv_bytes", "lost_bytes",
|
||||
"stream_retrans_bytes", "pmtu", "delivery_rate", "peer_max_idle_timeout",
|
||||
"peer_max_udp_payload_size", "peer_initial_max_data", "peer_initial_max_stream_data_bidi_local",
|
||||
"peer_initial_max_stream_data_bidi_remote", "peer_initial_max_stream_data_uni",
|
||||
"peer_initial_max_streams_bidi", "peer_initial_max_streams_uni", "peer_ack_delay_exponent",
|
||||
"peer_max_ack_delay", "peer_disable_active_migration", "peer_active_conn_id_limit",
|
||||
"peer_max_datagram_frame_size"
|
||||
})
|
||||
class quiche_stats extends Structure
|
||||
{
|
||||
// The number of QUIC packets received on this connection.
|
||||
|
@ -335,11 +339,11 @@ public interface LibQuiche extends Library
|
|||
interface packet_type
|
||||
{
|
||||
byte INITIAL = 1,
|
||||
RETRY = 2,
|
||||
HANDSHAKE = 3,
|
||||
ZERO_RTT = 4,
|
||||
SHORT = 5,
|
||||
VERSION_NEGOTIATION = 6;
|
||||
RETRY = 2,
|
||||
HANDSHAKE = 3,
|
||||
ZERO_RTT = 4,
|
||||
SHORT = 5,
|
||||
VERSION_NEGOTIATION = 6;
|
||||
|
||||
static String typeToString(byte type)
|
||||
{
|
||||
|
@ -377,10 +381,10 @@ public interface LibQuiche extends Library
|
|||
|
||||
// Writes a retry packet.
|
||||
ssize_t quiche_retry(byte[] scid, size_t scid_len,
|
||||
byte[] dcid, size_t dcid_len,
|
||||
byte[] new_scid, size_t new_scid_len,
|
||||
byte[] token, size_t token_len,
|
||||
uint32_t version, ByteBuffer out, size_t out_len);
|
||||
byte[] dcid, size_t dcid_len,
|
||||
byte[] new_scid, size_t new_scid_len,
|
||||
byte[] token, size_t token_len,
|
||||
uint32_t version, ByteBuffer out, size_t out_len);
|
||||
|
||||
// Creates a new server-side connection.
|
||||
quiche_conn quiche_accept(byte[] scid, size_t scid_len, byte[] odcid, size_t odcid_len, sockaddr from, size_t from_len, quiche_config config);
|
||||
|
@ -460,7 +464,8 @@ public interface LibQuiche extends Library
|
|||
public byte dummy;
|
||||
}
|
||||
|
||||
interface quiche_shutdown {
|
||||
interface quiche_shutdown
|
||||
{
|
||||
int QUICHE_SHUTDOWN_READ = 0,
|
||||
QUICHE_SHUTDOWN_WRITE = 1;
|
||||
}
|
||||
|
|
|
@ -194,13 +194,13 @@ public class QuicServerConnector extends AbstractNetworkConnector
|
|||
try
|
||||
{
|
||||
datagramChannel.bind(bindAddress);
|
||||
return datagramChannel;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
IO.close(datagramChannel);
|
||||
throw new IOException("Failed to bind to " + bindAddress, e);
|
||||
}
|
||||
return datagramChannel;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue