Skip to content

Commit

Permalink
#8695: update quiche to version 0.15.0
Browse files Browse the repository at this point in the history
Signed-off-by: Ludovic Orban <[email protected]>
  • Loading branch information
lorban committed Oct 18, 2022
1 parent d9b6aa0 commit d6a101d
Show file tree
Hide file tree
Showing 15 changed files with 402 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ public Runnable process(SocketAddress remoteAddress, ByteBuffer cipherBufferIn)
int remaining = cipherBufferIn.remaining();
if (LOG.isDebugEnabled())
LOG.debug("feeding {} cipher bytes to {}", remaining, this);
int accepted = quicheConnection.feedCipherBytes(cipherBufferIn, remoteAddress);
int accepted = quicheConnection.feedCipherBytes(cipherBufferIn, getLocalAddress(), remoteAddress);
if (accepted != remaining)
throw new IllegalStateException();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public interface Quiche
interface quiche_cc_algorithm
{
int QUICHE_CC_RENO = 0,
QUICHE_CC_CUBIC = 1;
QUICHE_CC_CUBIC = 1,
QUICHE_CC_BBR = 2;
}

interface quiche_error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public class QuicheConfig
public enum CongestionControl
{
RENO(Quiche.quiche_cc_algorithm.QUICHE_CC_RENO),
CUBIC(Quiche.quiche_cc_algorithm.QUICHE_CC_CUBIC);
CUBIC(Quiche.quiche_cc_algorithm.QUICHE_CC_CUBIC),
BBR(Quiche.quiche_cc_algorithm.QUICHE_CC_BBR);

private final int value;
CongestionControl(int value)
Expand Down Expand Up @@ -46,6 +47,9 @@ public int getValue()
private Long initialMaxStreamsBidi;
private Long initialMaxStreamsUni;
private Boolean disableActiveMigration;
private Long maxConnectionWindow;
private Long maxStreamWindow;
private Long activeConnectionIdLimit;

public QuicheConfig()
{
Expand Down Expand Up @@ -121,6 +125,21 @@ public Boolean getDisableActiveMigration()
return disableActiveMigration;
}

public Long getMaxConnectionWindow()
{
return maxConnectionWindow;
}

public Long getMaxStreamWindow()
{
return maxStreamWindow;
}

public Long getActiveConnectionIdLimit()
{
return activeConnectionIdLimit;
}

public void setVersion(int version)
{
this.version = version;
Expand Down Expand Up @@ -191,4 +210,18 @@ public void setDisableActiveMigration(Boolean disable)
this.disableActiveMigration = disable;
}

public void setMaxConnectionWindow(Long sizeInBytes)
{
this.maxConnectionWindow = sizeInBytes;
}

public void setMaxStreamWindow(Long maxStreamWindow)
{
this.maxStreamWindow = maxStreamWindow;
}

public void setActiveConnectionIdLimit(Long activeConnectionIdLimit)
{
this.activeConnectionIdLimit = activeConnectionIdLimit;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,12 @@ public final List<Long> writableStreamIds()
/**
* Read the buffer of cipher text coming from the network.
* @param buffer the buffer to read.
* @param local the local address on which the buffer was received.
* @param peer the address of the peer from which the buffer was received.
* @return how many bytes were consumed.
* @throws IOException
*/
public abstract int feedCipherBytes(ByteBuffer buffer, SocketAddress peer) throws IOException;
public abstract int feedCipherBytes(ByteBuffer buffer, SocketAddress local, SocketAddress peer) throws IOException;

/**
* Fill the given buffer with cipher text to be sent.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public class ForeignIncubatorQuicheConnection extends QuicheConnection
private MemorySegment sendInfo;
private MemorySegment recvInfo;
private MemorySegment stats;
private MemorySegment pathStats;

private ForeignIncubatorQuicheConnection(MemoryAddress quicheConn, MemoryAddress quicheConfig, ResourceScope scope)
{
Expand All @@ -62,6 +63,7 @@ private ForeignIncubatorQuicheConnection(MemoryAddress quicheConn, MemoryAddress
this.sendInfo = quiche_send_info.allocate(scope);
this.recvInfo = quiche_recv_info.allocate(scope);
this.stats = quiche_stats.allocate(scope);
this.pathStats = quiche_path_stats.allocate(scope);
}

public static byte[] fromPacket(ByteBuffer packet)
Expand Down Expand Up @@ -124,12 +126,12 @@ public static byte[] fromPacket(ByteBuffer packet)
}
}

public static ForeignIncubatorQuicheConnection connect(QuicheConfig quicheConfig, InetSocketAddress peer) throws IOException
public static ForeignIncubatorQuicheConnection connect(QuicheConfig quicheConfig, InetSocketAddress local, InetSocketAddress peer) throws IOException
{
return connect(quicheConfig, peer, QUICHE_MAX_CONN_ID_LEN);
return connect(quicheConfig, local, peer, QUICHE_MAX_CONN_ID_LEN);
}

public static ForeignIncubatorQuicheConnection connect(QuicheConfig quicheConfig, InetSocketAddress peer, int connectionIdLength) throws IOException
public static ForeignIncubatorQuicheConnection connect(QuicheConfig quicheConfig, InetSocketAddress local, InetSocketAddress peer, int connectionIdLength) throws IOException
{
if (connectionIdLength > QUICHE_MAX_CONN_ID_LEN)
throw new IOException("Connection ID length is too large: " + connectionIdLength + " > " + QUICHE_MAX_CONN_ID_LEN);
Expand All @@ -144,8 +146,9 @@ public static ForeignIncubatorQuicheConnection connect(QuicheConfig quicheConfig
scid.asByteBuffer().put(scidBytes);
MemoryAddress libQuicheConfig = buildConfig(quicheConfig, scope);

MemorySegment s = sockaddr.convert(peer, scope);
MemoryAddress quicheConn = quiche_h.quiche_connect(CLinker.toCString(peer.getHostName(), scope), scid, scid.byteSize(), s, s.byteSize(), libQuicheConfig);
MemorySegment localSockaddr = sockaddr.convert(local, scope);
MemorySegment peerSockaddr = sockaddr.convert(peer, scope);
MemoryAddress quicheConn = quiche_h.quiche_connect(CLinker.toCString(peer.getHostName(), scope), scid, scid.byteSize(), localSockaddr, localSockaddr.byteSize(), peerSockaddr, peerSockaddr.byteSize(), libQuicheConfig);
ForeignIncubatorQuicheConnection connection = new ForeignIncubatorQuicheConnection(quicheConn, libQuicheConfig, scope);
keepScope = true;
return connection;
Expand Down Expand Up @@ -227,6 +230,18 @@ private static MemoryAddress buildConfig(QuicheConfig config, ResourceScope scop
if (disableActiveMigration != null)
quiche_h.quiche_config_set_disable_active_migration(quicheConfig, disableActiveMigration ? C_TRUE : C_FALSE);

Long maxConnectionWindow = config.getMaxConnectionWindow();
if (maxConnectionWindow != null)
quiche_h.quiche_config_set_max_connection_window(quicheConfig, maxConnectionWindow);

Long maxStreamWindow = config.getMaxStreamWindow();
if (maxStreamWindow != null)
quiche_h.quiche_config_set_max_stream_window(quicheConfig, maxStreamWindow);

Long activeConnectionIdLimit = config.getActiveConnectionIdLimit();
if (activeConnectionIdLimit != null)
quiche_h.quiche_config_set_active_connection_id_limit(quicheConfig, activeConnectionIdLimit);

return quicheConfig;
}

Expand Down Expand Up @@ -354,7 +369,7 @@ public static boolean negotiate(TokenMinter tokenMinter, ByteBuffer packetRead,
}
}

public static ForeignIncubatorQuicheConnection tryAccept(QuicheConfig quicheConfig, TokenValidator tokenValidator, ByteBuffer packetRead, SocketAddress peer) throws IOException
public static ForeignIncubatorQuicheConnection tryAccept(QuicheConfig quicheConfig, TokenValidator tokenValidator, ByteBuffer packetRead, SocketAddress local, SocketAddress peer) throws IOException
{
boolean keepScope = false;
ResourceScope scope = ResourceScope.newSharedScope();
Expand Down Expand Up @@ -442,8 +457,9 @@ public static ForeignIncubatorQuicheConnection tryAccept(QuicheConfig quicheConf
LOG.debug("connection creation...");
MemoryAddress libQuicheConfig = buildConfig(quicheConfig, scope);

MemorySegment s = sockaddr.convert(peer, scope);
MemoryAddress quicheConn = quiche_h.quiche_accept(dcid.address(), getLong(dcid_len), odcid.address(), odcid.byteSize(), s.address(), s.byteSize(), libQuicheConfig);
MemorySegment localSockaddr = sockaddr.convert(local, scope);
MemorySegment peerSockaddr = sockaddr.convert(peer, scope);
MemoryAddress quicheConn = quiche_h.quiche_accept(dcid.address(), getLong(dcid_len), odcid.address(), odcid.byteSize(), localSockaddr.address(), localSockaddr.byteSize(), peerSockaddr.address(), peerSockaddr.byteSize(), libQuicheConfig);
if (quicheConn == null)
{
quiche_h.quiche_config_free(libQuicheConfig);
Expand All @@ -455,7 +471,7 @@ public static ForeignIncubatorQuicheConnection tryAccept(QuicheConfig quicheConf
LOG.debug("accepted, immediately receiving the same packet - remaining in buffer: {}", packetRead.remaining());
while (packetRead.hasRemaining())
{
quicheConnection.feedCipherBytes(packetRead, peer);
quicheConnection.feedCipherBytes(packetRead, local, peer);
}
keepScope = true;
return quicheConnection;
Expand Down Expand Up @@ -498,7 +514,7 @@ protected List<Long> iterableStreamIds(boolean write)
}

@Override
public int feedCipherBytes(ByteBuffer buffer, SocketAddress peer) throws IOException
public int feedCipherBytes(ByteBuffer buffer, SocketAddress local, SocketAddress peer) throws IOException
{
try (AutoLock ignore = lock.lock())
{
Expand All @@ -508,7 +524,7 @@ public int feedCipherBytes(ByteBuffer buffer, SocketAddress peer) throws IOExcep
long received;
try (ResourceScope scope = ResourceScope.newConfinedScope())
{
quiche_recv_info.setSocketAddress(recvInfo, peer, scope);
quiche_recv_info.setSocketAddress(recvInfo, local, peer, scope);
if (buffer.isDirect())
{
// If the ByteBuffer is direct, it can be used without any copy.
Expand Down Expand Up @@ -696,6 +712,7 @@ public void dispose()
sendInfo = null;
recvInfo = null;
stats = null;
pathStats = null;
}
}

Expand Down Expand Up @@ -729,8 +746,8 @@ public long windowCapacity()
{
if (quicheConn == null)
throw new IllegalStateException("connection was released");
quiche_h.quiche_conn_stats(quicheConn, stats.address());
return quiche_stats.get_cwnd(stats);
quiche_h.quiche_conn_path_stats(quicheConn, pathStats.address());
return quiche_path_stats.get_cwnd(stats);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class quiche_h
{
// This interface is a translation of the quiche.h header of a specific version.
// It needs to be reviewed each time the native lib version changes.
private static final String EXPECTED_QUICHE_VERSION = "0.12.0";
private static final String EXPECTED_QUICHE_VERSION = "0.15.0";

public static final byte C_FALSE = 0;
public static final byte C_TRUE = 1;
Expand Down Expand Up @@ -142,6 +142,24 @@ public class quiche_h
FunctionDescriptor.ofVoid(C_POINTER, C_CHAR)
);

private static final MethodHandle quiche_config_set_max_connection_window$MH = downcallHandle(
"quiche_config_set_max_connection_window",
"(Ljdk/incubator/foreign/MemoryAddress;J)V",
FunctionDescriptor.ofVoid(C_POINTER, C_LONG)
);

private static final MethodHandle quiche_config_set_max_stream_window$MH = downcallHandle(
"quiche_config_set_max_stream_window",
"(Ljdk/incubator/foreign/MemoryAddress;J)V",
FunctionDescriptor.ofVoid(C_POINTER, C_LONG)
);

private static final MethodHandle quiche_config_set_active_connection_id_limit$MH = downcallHandle(
"quiche_config_set_active_connection_id_limit",
"(Ljdk/incubator/foreign/MemoryAddress;J)V",
FunctionDescriptor.ofVoid(C_POINTER, C_LONG)
);

private static final MethodHandle quiche_config_free$MH = downcallHandle(
"quiche_config_free",
"(Ljdk/incubator/foreign/MemoryAddress;)V",
Expand All @@ -150,8 +168,8 @@ public class quiche_h

private static final MethodHandle quiche_connect$MH = downcallHandle(
"quiche_connect",
"(Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemoryAddress;",
FunctionDescriptor.of(C_POINTER, C_POINTER, C_POINTER, C_LONG, C_POINTER, C_LONG, C_POINTER)
"(Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemoryAddress;",
FunctionDescriptor.of(C_POINTER, C_POINTER, C_POINTER, C_LONG, C_POINTER, C_LONG, C_POINTER, C_LONG, C_POINTER)
);

private static final MethodHandle quiche_conn_send$MH = downcallHandle(
Expand All @@ -174,8 +192,8 @@ public class quiche_h

private static final MethodHandle quiche_accept$MH = downcallHandle(
"quiche_accept",
"(Ljdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemoryAddress;",
FunctionDescriptor.of(C_POINTER, C_POINTER, C_LONG, C_POINTER, C_LONG, C_POINTER, C_LONG, C_POINTER)
"(Ljdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemoryAddress;",
FunctionDescriptor.of(C_POINTER, C_POINTER, C_LONG, C_POINTER, C_LONG, C_POINTER, C_LONG, C_POINTER, C_LONG, C_POINTER)
);

private static final MethodHandle quiche_negotiate_version$MH = downcallHandle(
Expand Down Expand Up @@ -244,6 +262,12 @@ public class quiche_h
FunctionDescriptor.ofVoid(C_POINTER, C_POINTER)
);

private static final MethodHandle quiche_conn_path_stats$MH = downcallHandle(
"quiche_conn_path_stats",
"(Ljdk/incubator/foreign/MemoryAddress;JLjdk/incubator/foreign/MemoryAddress;)I",
FunctionDescriptor.of(C_INT, C_POINTER, C_LONG, C_POINTER)
);

private static final MethodHandle quiche_conn_stream_finished$MH = downcallHandle(
"quiche_conn_stream_finished",
"(Ljdk/incubator/foreign/MemoryAddress;J)B",
Expand Down Expand Up @@ -412,6 +436,42 @@ public static void quiche_config_set_disable_active_migration(MemoryAddress conf
}
}

public static void quiche_config_set_max_connection_window(MemoryAddress config, long v)
{
try
{
quiche_config_set_max_connection_window$MH.invokeExact(config, v);
}
catch (Throwable ex)
{
throw new AssertionError("should not reach here", ex);
}
}

public static void quiche_config_set_max_stream_window(MemoryAddress config, long v)
{
try
{
quiche_config_set_max_stream_window$MH.invokeExact(config, v);
}
catch (Throwable ex)
{
throw new AssertionError("should not reach here", ex);
}
}

public static void quiche_config_set_active_connection_id_limit(MemoryAddress config, long v)
{
try
{
quiche_config_set_active_connection_id_limit$MH.invokeExact(config, v);
}
catch (Throwable ex)
{
throw new AssertionError("should not reach here", ex);
}
}

public static void quiche_config_set_initial_max_data(MemoryAddress config, long v)
{
try
Expand Down Expand Up @@ -544,11 +604,11 @@ public static void quiche_config_free(MemoryAddress config)
}
}

public static MemoryAddress quiche_connect(Addressable server_name, Addressable scid, long scid_len, Addressable to, long to_len, Addressable config)
public static MemoryAddress quiche_connect(Addressable server_name, Addressable scid, long scid_len, Addressable local, long local_len, Addressable peer, long peer_len, Addressable config)
{
try
{
return (MemoryAddress) quiche_connect$MH.invokeExact(server_name.address(), scid.address(), scid_len, to.address(), to_len, config.address());
return (MemoryAddress) quiche_connect$MH.invokeExact(server_name.address(), scid.address(), scid_len, local.address(), local_len, peer.address(), peer_len, config.address());
}
catch (Throwable ex)
{
Expand Down Expand Up @@ -700,6 +760,18 @@ public static void quiche_conn_stats(MemoryAddress conn, MemoryAddress stats)
}
}

public static int quiche_conn_path_stats(MemoryAddress conn, MemoryAddress stats)
{
try
{
return (int)quiche_conn_path_stats$MH.invokeExact(conn, stats);
}
catch (Throwable ex)
{
throw new AssertionError("should not reach here", ex);
}
}

public static void quiche_conn_on_timeout(MemoryAddress conn)
{
try
Expand Down Expand Up @@ -822,12 +894,13 @@ public static byte quiche_version_is_supported(int version)

public static MemoryAddress quiche_accept(MemoryAddress scid, long scid_len,
MemoryAddress odcid, long odcid_len,
MemoryAddress from, long from_len,
MemoryAddress local, long local_len,
MemoryAddress peer, long peer_len,
MemoryAddress config)
{
try
{
return (MemoryAddress)quiche_accept$MH.invokeExact(scid, scid_len, odcid, odcid_len, from, from_len, config);
return (MemoryAddress)quiche_accept$MH.invokeExact(scid, scid_len, odcid, odcid_len, local, local_len, peer, peer_len, config);
}
catch (Throwable ex)
{
Expand Down
Loading

0 comments on commit d6a101d

Please sign in to comment.