Skip to content

Commit d3d5d7e

Browse files
committed
Quic stream reset handling improvements.
Motivation: The initial implementation of stream reset handling closes the stream upon reception of a reset frame when a stream handler is present. It is the desired default behavior, however a stream having sent or received a reset frame can still process or read data on the other direction. Setting a handler on the stream makes the application aware of the reset and when it happens the stream should not be closed (that is writing a final stream frame) and instead the application should take care of it at the most appropriate time the protocol requires it. Changes: Setting a quic stream handler inhibates exception handling and stream closing.
1 parent 8f1aaf8 commit d3d5d7e

File tree

12 files changed

+192
-19
lines changed

12 files changed

+192
-19
lines changed

vertx-core/src/main/java/io/vertx/core/datagram/impl/DatagramSocketImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ public NetworkMetrics metrics() {
348348
}
349349

350350
@Override
351-
protected void handleException(Throwable t) {
351+
protected boolean handleException(Throwable t) {
352352
super.handleException(t);
353353
Handler<Throwable> handler;
354354
synchronized (DatagramSocketImpl.this) {
@@ -357,6 +357,7 @@ protected void handleException(Throwable t) {
357357
if (handler != null) {
358358
handler.handle(t);
359359
}
360+
return true;
360361
}
361362

362363
@Override

vertx-core/src/main/java/io/vertx/core/http/impl/http1x/Http1xClientConnection.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,8 +1222,8 @@ protected void handleIdle(IdleStateEvent event) {
12221222
}
12231223

12241224
@Override
1225-
public void handleException(Throwable e) {
1226-
super.handleException(e);
1225+
public boolean handleException(Throwable e) {
1226+
boolean ret = super.handleException(e);
12271227
LinkedHashSet<Stream> allStreams = new LinkedHashSet<>();
12281228
synchronized (this) {
12291229
allStreams.addAll(requests);
@@ -1232,6 +1232,7 @@ public void handleException(Throwable e) {
12321232
for (Stream stream : allStreams) {
12331233
stream.handleException(e);
12341234
}
1235+
return ret;
12351236
}
12361237

12371238
@Override

vertx-core/src/main/java/io/vertx/core/http/impl/http1x/Http1xServerConnection.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,8 +472,8 @@ protected void handleClosed() {
472472
}
473473

474474
@Override
475-
public void handleException(Throwable t) {
476-
super.handleException(t);
475+
public boolean handleException(Throwable t) {
476+
boolean ret = super.handleException(t);
477477
Http1xServerRequest responseInProgress = this.responseInProgress;
478478
Http1xServerRequest requestInProgress = this.requestInProgress;
479479
if (requestInProgress != null) {
@@ -484,6 +484,7 @@ public void handleException(Throwable t) {
484484
responseInProgress.reportMetricsFailed = true;
485485
responseInProgress.handleException(t);
486486
}
487+
return ret;
487488
}
488489

489490
@Override

vertx-core/src/main/java/io/vertx/core/http/impl/websocket/WebSocketConnectionImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,12 @@ private CloseWebSocketFrame closeFrame(short statusCode, String reason) {
136136
}
137137

138138
@Override
139-
public void handleException(Throwable t) {
139+
public boolean handleException(Throwable t) {
140140
WebSocketImplBase<?> ws = webSocket;
141141
if (ws != null) {
142142
ws.context().execute(t, ws::handleException);
143143
}
144+
return true;
144145
}
145146

146147
@Override

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,13 @@ public interface QuicStream extends Socket {
4242
QuicConnection connection();
4343

4444
/**
45-
* Set a handler called upon stream reset.
45+
* <p>Set a handler called upon stream reset: when a stream receives a reset frame from its peer,
46+
* this handler is called.</p>
47+
*
48+
* <p>When no such handler is set, the stream exception handler is called and then the stream is automatically
49+
* closed. Setting this handler changes this behavior: the handler processes the reset event and the handler
50+
* has the full responsibility of managing the stream. That means the sending part of this stream is left
51+
* untouched and the application can continue sending data.</p>
4652
*
4753
* @param handler the handler
4854
* @return this instance of a stream

vertx-core/src/main/java/io/vertx/core/net/impl/ConnectionBase.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ public NetworkMetrics metrics() {
160160
return null;
161161
}
162162

163-
protected void handleException(Throwable t) {
163+
protected boolean handleException(Throwable t) {
164164
NetworkMetrics metrics = metrics();
165165
if (metrics != null) {
166166
metrics.exceptionOccurred(metric, remoteAddress(), t);
@@ -180,6 +180,7 @@ protected void handleException(Throwable t) {
180180
}
181181
}
182182
});
183+
return true;
183184
}
184185

185186
protected void handleClosed() {

vertx-core/src/main/java/io/vertx/core/net/impl/VertxHandler.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,15 @@ public void channelWritabilityChanged(ChannelHandlerContext ctx) {
144144
@Override
145145
public void exceptionCaught(ChannelHandlerContext chctx, final Throwable t) {
146146
C connection = getConnection();
147+
boolean close;
147148
if (connection != null) {
148-
connection.handleException(t);
149+
close = connection.handleException(t);
150+
} else {
151+
close = true;
152+
}
153+
if (close) {
154+
chctx.close();
149155
}
150-
chctx.close();
151156
}
152157

153158
@Override

vertx-core/src/main/java/io/vertx/core/net/impl/quic/QuicConnectionHandler.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,9 @@ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exc
104104

105105
@Override
106106
public void exceptionCaught(ChannelHandlerContext chctx, final Throwable t) {
107-
connection.handleException(t);
108-
chctx.close();
107+
if (connection.handleException(t)) {
108+
chctx.close();
109+
}
109110
}
110111

111112
@Override

vertx-core/src/main/java/io/vertx/core/net/impl/quic/QuicConnectionImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ public QuicConnectionImpl closeHandler(Handler<Void> handler) {
131131
}
132132

133133
@Override
134-
protected void handleException(Throwable t) {
135-
super.handleException(t);
134+
protected boolean handleException(Throwable t) {
135+
return super.handleException(t);
136136
}
137137

138138
void handleClosed(QuicConnectionClose payload) {

vertx-core/src/main/java/io/vertx/core/net/impl/quic/QuicStreamImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,18 +115,18 @@ protected void handleEvent(Object event) {
115115
}
116116

117117
@Override
118-
protected void handleException(Throwable t) {
118+
protected boolean handleException(Throwable t) {
119119
if (t instanceof QuicException) {
120120
QuicException quicException = (QuicException) t;
121121
if (quicException.error() == null && "STREAM_RESET".equals(quicException.getMessage())) {
122122
Handler<Integer> handler = resetHandler;
123123
if (handler != null) {
124124
context.emit(0, handler);
125+
return false;
125126
}
126-
return;
127127
}
128128
}
129-
super.handleException(t);
129+
return super.handleException(t);
130130
}
131131

132132
@Override

0 commit comments

Comments
 (0)