Skip to content

Commit

Permalink
Protect against re-entrancy in connectionSend() (java-native-access#205)
Browse files Browse the repository at this point in the history
Motivation:

connectionSend() may be entered in a reentrance fashion. We should prevent this.

Modifications:

Add flag that guards against re-entrancy

Result:

No more re-entrancy in connectionSend()
  • Loading branch information
normanmaurer authored Mar 1, 2021
1 parent e53a7c2 commit 3313490
Showing 1 changed file with 34 additions and 27 deletions.
61 changes: 34 additions & 27 deletions src/main/java/io/netty/incubator/codec/quic/QuicheQuicChannel.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ public void operationComplete(ChannelFuture future) {
private boolean recvStreamPending;
private boolean streamReadable;
private boolean inRecv;
private boolean inConnectionSend;

private static final int CLOSED = 0;
private static final int OPEN = 1;
Expand Down Expand Up @@ -969,43 +970,49 @@ private boolean isConnDestroyed() {
* {@link Channel#flush()} at some point.
*/
private boolean connectionSend() {
if (isConnDestroyed()) {
if (isConnDestroyed() || inConnectionSend) {
return false;
}

long connAddr = connection.address();
boolean packetWasWritten = false;
for (;;) {
ByteBuf out = alloc().directBuffer(Quic.MAX_DATAGRAM_SIZE);
int writerIndex = out.writerIndex();
int written = Quiche.quiche_conn_send(
connAddr, Quiche.memoryAddress(out) + writerIndex, out.writableBytes());
inConnectionSend = true;

try {
if (Quiche.throwIfError(written)) {
try {
long connAddr = connection.address();
boolean packetWasWritten = false;
for (;;) {
ByteBuf out = alloc().directBuffer(Quic.MAX_DATAGRAM_SIZE);
int writerIndex = out.writerIndex();
int written = Quiche.quiche_conn_send(
connAddr, Quiche.memoryAddress(out) + writerIndex, out.writableBytes());

try {
if (Quiche.throwIfError(written)) {
out.release();
break;
}
} catch (Exception e) {
out.release();
pipeline().fireExceptionCaught(e);
break;
}
} catch (Exception e) {
out.release();
pipeline().fireExceptionCaught(e);
break;
}

if (written == 0) {
// No need to create a new datagram packet. Just release and try again.
out.release();
continue;
if (written == 0) {
// No need to create a new datagram packet. Just release and try again.
out.release();
continue;
}
out.writerIndex(writerIndex + written);
parent().write(new DatagramPacket(out, remote));
packetWasWritten = true;
}
out.writerIndex(writerIndex + written);
parent().write(new DatagramPacket(out, remote));
packetWasWritten = true;
}
if (packetWasWritten) {
timeoutHandler.scheduleTimeout();
return true;
if (packetWasWritten) {
timeoutHandler.scheduleTimeout();
return true;
}
return false;
} finally {
inConnectionSend = false;
}
return false;
}

private final class QuicChannelUnsafe extends AbstractChannel.AbstractUnsafe {
Expand Down

0 comments on commit 3313490

Please sign in to comment.