Skip to content

Commit

Permalink
Add method to retrieve peer transport parameters (java-native-access#597
Browse files Browse the repository at this point in the history
)

Motivation:

It is useful to be able to retrieve what limits the peer has set as
transport parameters.

Modifications:

Add method to be able to retrieve transport parameters sent by the
remote peer

Result:

Be able to inspect transport parameters that might enforce limits etc
  • Loading branch information
normanmaurer authored Oct 26, 2023
1 parent bdadcb8 commit fd02b1c
Show file tree
Hide file tree
Showing 9 changed files with 363 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ default ChannelPromise voidPromise() {
*/
boolean isTimedOut();

/**
* Returns the {@link QuicTransportParameters} of the peer once received, or {@code null} if not known yet.
*
* @return peerTransportParams.
*/
QuicTransportParameters peerTransportParameters();

/**
* Creates a stream that is using this {@link QuicChannel} and notifies the {@link Future} once done.
* The {@link ChannelHandler} (if not {@code null}) is added to the {@link io.netty.channel.ChannelPipeline} of the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

/**
* Statistics about the {@code QUIC} connection. If unknown by the implementation it might return {@code -1} values
* for the various methods.
* for the various methods.
*/
public interface QuicConnectionStats {
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright 2023 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.incubator.codec.quic;

/**
* Transport parameters for QUIC.
*/
public interface QuicTransportParameters {

/**
* The maximum idle timeout.
* @return timeout.
*/
long maxIdleTimeout();

/**
* The maximum UDP payload size.
*
* @return maximum payload size.
*/
long maxUdpPayloadSize();

/**
* The initial flow control maximum data for the connection.
*
* @return flowcontrol.
*/
long initialMaxData();

/**
* The initial flow control maximum data for local bidirectional streams.
*
* @return flowcontrol.
*/
long initialMaxStreamDataBidiLocal();

/**
* The initial flow control maximum data for remote bidirectional streams.
*
* @return flowcontrol.
*/
long initialMaxStreamDataBidiRemote();

/**
* The initial flow control maximum data for unidirectional streams.
*
* @return flowcontrol.
*/
long initialMaxStreamDataUni();


/**
* The initial maximum bidirectional streams.
*
* @return streams.
*/
long initialMaxStreamsBidi();

/**
* The initial maximum unidirectional streams.
*
* @return streams.
*/
long initialMaxStreamsUni();

/**
* The ACK delay exponent
*
* @return exponent.
*/
long ackDelayExponent();

/**
* The max ACK delay.
*
* @return delay.
*/
long maxAckDelay();

/**
* Whether active migration is disabled.
*
* @return disabled.
*/
boolean disableActiveMigration();

/**
* The active connection ID limit.
*
* @return limit.
*/
long activeConnIdLimit();

/**
* DATAGRAM frame extension parameter, if any.
*
* @return param.
*/
long maxDatagramFrameSize();
}
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,13 @@ static native int quiche_conn_stream_priority(
*/
static native long[] quiche_conn_stats(long connAddr);

/**
* See
* <a href="https://github.com/cloudflare/quiche/blob/master/quiche/include/quiche.h#L567C65-L567C88">
* quiche_conn_stats</a>.
*/
static native long[] quiche_conn_peer_transport_params(long connAddr);

/**
* See
* <a href="https://github.com/cloudflare/quiche/blob/0.6.0/include/quiche.h#L288">quiche_conn_timeout_as_nanos</a>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1840,4 +1840,9 @@ private QuicConnectionStats collectStats0(QuicheQuicConnection connection, Promi
promise.setSuccess(connStats);
return connStats;
}

@Override
public QuicTransportParameters peerTransportParameters() {
return connection.peerParameters();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,20 @@ QuicConnectionAddress connectionId(Supplier<byte[]> idSupplier) {
return id == null ? null : new QuicConnectionAddress(id);
}

QuicheQuicTransportParameters peerParameters() {
final long[] ret;
synchronized (this) {
if (connection == -1) {
return null;
}
ret = Quiche.quiche_conn_peer_transport_params(connection);
}
if (ret == null) {
return null;
}
return new QuicheQuicTransportParameters(ret);
}

QuicheQuicSslEngine engine() {
return engine;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright 2023 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.incubator.codec.quic;

final class QuicheQuicTransportParameters implements QuicTransportParameters {
private final long[] values;

QuicheQuicTransportParameters(long[] values) {
this.values = values;
}

@Override
public long maxIdleTimeout() {
return values[0];
}

@Override
public long maxUdpPayloadSize() {
return values[1];
}

@Override
public long initialMaxData() {
return values[2];
}

@Override
public long initialMaxStreamDataBidiLocal() {
return values[3];
}

@Override
public long initialMaxStreamDataBidiRemote() {
return values[4];
}

@Override
public long initialMaxStreamDataUni() {
return values[5];
}

@Override
public long initialMaxStreamsBidi() {
return values[6];
}

@Override
public long initialMaxStreamsUni() {
return values[7];
}

@Override
public long ackDelayExponent() {
return values[8];
}

@Override
public long maxAckDelay() {
return values[9];
}

@Override
public boolean disableActiveMigration() {
return values[10] == 1;
}

@Override
public long activeConnIdLimit() {
return values[11];
}

@Override
public long maxDatagramFrameSize() {
return values[12];
}
}
33 changes: 33 additions & 0 deletions codec-native-quic/src/main/c/netty_quic_quiche.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,38 @@ static jlongArray netty_quiche_conn_stats(JNIEnv* env, jclass clazz, jlong conn)
return statsArray;
}

static jlongArray netty_quiche_conn_peer_transport_params(JNIEnv* env, jclass clazz, jlong conn) {
// See https://github.com/cloudflare/quiche/blob/master/quiche/include/quiche.h#L563
quiche_transport_params params = {0,0,0,0,0,0,0,0,0,0,false,0,0};
if (!quiche_conn_peer_transport_params((quiche_conn *) conn, &params)) {
return NULL;
}

jlongArray paramsArray = (*env)->NewLongArray(env, 13);
if (paramsArray == NULL) {
// This will put an OOME on the stack
return NULL;
}
jlong paramsArrayElements[] = {
(jlong)params.peer_max_idle_timeout,
(jlong)params.peer_max_udp_payload_size,
(jlong)params.peer_initial_max_data,
(jlong)params.peer_initial_max_stream_data_bidi_local,
(jlong)params.peer_initial_max_stream_data_bidi_remote,
(jlong)params.peer_initial_max_stream_data_uni,
(jlong)params.peer_initial_max_streams_bidi,
(jlong)params.peer_initial_max_streams_uni,
(jlong)params.peer_ack_delay_exponent,
(jlong)params.peer_disable_active_migration ? 1: 0,
(jlong)params.peer_active_conn_id_limit,
(jlong)params.peer_max_datagram_frame_size
};
(*env)->SetLongArrayRegion(env, paramsArray, 0, 13, paramsArrayElements);
return paramsArray;
}



static jlong netty_quiche_conn_timeout_as_nanos(JNIEnv* env, jclass clazz, jlong conn) {
return quiche_conn_timeout_as_nanos((quiche_conn *) conn);
}
Expand Down Expand Up @@ -839,6 +871,7 @@ static const JNINativeMethod fixed_method_table[] = {
{ "quiche_conn_is_closed", "(J)Z", (void *) netty_quiche_conn_is_closed },
{ "quiche_conn_is_timed_out", "(J)Z", (void *) netty_quiche_conn_is_timed_out },
{ "quiche_conn_stats", "(J)[J", (void *) netty_quiche_conn_stats },
{ "quiche_conn_peer_transport_params", "(J)[J", (void *) netty_quiche_conn_peer_transport_params },
{ "quiche_conn_timeout_as_nanos", "(J)J", (void *) netty_quiche_conn_timeout_as_nanos },
{ "quiche_conn_on_timeout", "(J)V", (void *) netty_quiche_conn_on_timeout },
{ "quiche_conn_readable", "(J)J", (void *) netty_quiche_conn_readable },
Expand Down
Loading

0 comments on commit fd02b1c

Please sign in to comment.