Merge pull request #10019 from qzhuyan/dev/william/quic-hidden-low-level-tunings
230222 feat(quic): add hidden low level settings for listeners.
This commit is contained in:
commit
df7e9db057
|
@ -1901,6 +1901,347 @@ base_listener_acceptors {
|
|||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_max_bytes_per_key {
|
||||
desc {
|
||||
en: "Maximum number of bytes to encrypt with a single 1-RTT encryption key before initiating key update. Default: 274877906944"
|
||||
zh: "在启动密钥更新之前,用单个 1-RTT 加密密钥加密的最大字节数。默认值:274877906944"
|
||||
}
|
||||
label {
|
||||
en: "Max bytes per key"
|
||||
zh: "每个密钥的最大字节数"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_handshake_idle_timeout_ms {
|
||||
desc {
|
||||
en: "How long a handshake can idle before it is discarded. Default: 10 000"
|
||||
zh: "一个握手在被丢弃之前可以空闲多长时间。 默认值:10 000"
|
||||
}
|
||||
label {
|
||||
en: "Handshake idle timeout ms"
|
||||
zh: "握手空闲超时毫秒"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_tls_server_max_send_buffer {
|
||||
desc {
|
||||
en: "How much Server TLS data to buffer. Default: 8192"
|
||||
zh: "缓冲多少TLS数据。 默认值:8192"
|
||||
}
|
||||
label {
|
||||
en: "TLS server max send buffer"
|
||||
zh: "TLS 服务器最大发送缓冲区"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_stream_recv_window_default {
|
||||
desc {
|
||||
en: "Initial stream receive window size. Default: 32678"
|
||||
zh: "初始流接收窗口大小。 默认值:32678"
|
||||
}
|
||||
label {
|
||||
en: "Stream recv window default"
|
||||
zh: "流接收窗口默认"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_stream_recv_buffer_default {
|
||||
desc {
|
||||
en: "Stream initial buffer size. Default: 4096"
|
||||
zh: "流的初始缓冲区大小。默认:4096"
|
||||
}
|
||||
label {
|
||||
en: "Stream recv buffer default"
|
||||
zh: "流媒体接收缓冲区默认值"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_conn_flow_control_window {
|
||||
desc {
|
||||
en: "Connection-wide flow control window. Default: 16777216"
|
||||
zh: "连接的流控窗口。默认:16777216"
|
||||
}
|
||||
label {
|
||||
en: "Conn flow control window"
|
||||
zh: "流控窗口"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_max_stateless_operations {
|
||||
desc {
|
||||
en: "The maximum number of stateless operations that may be queued on a worker at any one time. Default: 16"
|
||||
zh: "无状态操作的最大数量,在任何时候都可以在一个工作者上排队。默认值:16"
|
||||
}
|
||||
label {
|
||||
en: "Max stateless operations"
|
||||
zh: "最大无状态操作数"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_initial_window_packets {
|
||||
desc {
|
||||
en: "The size (in packets) of the initial congestion window for a connection. Default: 10"
|
||||
zh: "一个连接的初始拥堵窗口的大小(以包为单位)。默认值:10"
|
||||
}
|
||||
label {
|
||||
en: "Initial window packets"
|
||||
zh: "初始窗口数据包"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_send_idle_timeout_ms {
|
||||
desc {
|
||||
en: "Reset congestion control after being idle for amount of time. Default: 1000"
|
||||
zh: "在闲置一定时间后重置拥堵控制。默认值:1000"
|
||||
}
|
||||
label {
|
||||
en: "Send idle timeout ms"
|
||||
zh: "发送空闲超时毫秒"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_initial_rtt_ms {
|
||||
desc {
|
||||
en: "Initial RTT estimate."
|
||||
zh: "初始RTT估计"
|
||||
}
|
||||
label {
|
||||
en: "Initial RTT ms"
|
||||
zh: "Initial RTT 毫秒"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_max_ack_delay_ms {
|
||||
desc {
|
||||
en: "How long to wait after receiving data before sending an ACK. Default: 25"
|
||||
zh: "在收到数据后要等待多长时间才能发送一个ACK。默认值:25"
|
||||
}
|
||||
label {
|
||||
en: "Max ack delay ms"
|
||||
zh: "最大应答延迟 毫秒"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_disconnect_timeout_ms {
|
||||
desc {
|
||||
en: "How long to wait for an ACK before declaring a path dead and disconnecting. Default: 16000"
|
||||
zh: "在判定路径无效和断开连接之前,要等待多长时间的ACK。默认:16000"
|
||||
}
|
||||
label {
|
||||
en: "Disconnect timeout ms"
|
||||
zh: "断开连接超时 毫秒"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_idle_timeout_ms {
|
||||
desc {
|
||||
en: "How long a connection can go idle before it is gracefully shut down. 0 to disable timeout"
|
||||
zh: "一个连接在被优雅地关闭之前可以空闲多长时间。0 表示禁用超时"
|
||||
}
|
||||
label {
|
||||
en: "Idle timeout ms"
|
||||
zh: "空闲超时 毫秒"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_handshake_idle_timeout_ms {
|
||||
desc {
|
||||
en: "How long a handshake can idle before it is discarded"
|
||||
zh: "一个握手在被丢弃之前可以空闲多长时间"
|
||||
}
|
||||
label {
|
||||
en: "Handshake idle timeout ms"
|
||||
zh: "握手空闲超时 毫秒"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_keep_alive_interval_ms {
|
||||
desc {
|
||||
en: "How often to send PING frames to keep a connection alive."
|
||||
zh: "多长时间发送一次PING帧以保活连接。"
|
||||
}
|
||||
label {
|
||||
en: "Keep alive interval ms"
|
||||
zh: "保持活着的时间间隔 毫秒"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_peer_bidi_stream_count {
|
||||
desc {
|
||||
en: "Number of bidirectional streams to allow the peer to open."
|
||||
zh: "允许对端打开的双向流的数量"
|
||||
}
|
||||
label {
|
||||
en: "Peer bidi stream count"
|
||||
zh: "对端双向流的数量"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_peer_unidi_stream_count {
|
||||
desc {
|
||||
en: "Number of unidirectional streams to allow the peer to open."
|
||||
zh: "允许对端打开的单向流的数量"
|
||||
}
|
||||
label {
|
||||
en: "Peer unidi stream count"
|
||||
zh: "对端单向流的数量"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_retry_memory_limit {
|
||||
desc {
|
||||
en: "The percentage of available memory usable for handshake connections before stateless retry is used. Calculated as `N/65535`. Default: 65"
|
||||
zh: "在使用无状态重试之前,可用于握手连接的可用内存的百分比。计算为`N/65535`。默认值:65"
|
||||
}
|
||||
label {
|
||||
en: "Retry memory limit"
|
||||
zh: "重试内存限制"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_load_balancing_mode {
|
||||
desc {
|
||||
en: "0: Disabled, 1: SERVER_ID_IP, 2: SERVER_ID_FIXED. default: 0"
|
||||
zh: "0: 禁用, 1: SERVER_ID_IP, 2: SERVER_ID_FIXED. 默认: 0"
|
||||
}
|
||||
label {
|
||||
en: "Load balancing mode"
|
||||
zh: "负载平衡模式"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_max_operations_per_drain {
|
||||
desc {
|
||||
en: "The maximum number of operations to drain per connection quantum. Default: 16"
|
||||
zh: "每个连接操作的最大耗费操作数。默认:16"
|
||||
}
|
||||
label {
|
||||
en: "Max operations per drain"
|
||||
zh: "每次操作最大操作数"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_send_buffering_enabled {
|
||||
desc {
|
||||
en: "Buffer send data instead of holding application buffers until sent data is acknowledged. Default: 1 (Enabled)"
|
||||
zh: "缓冲发送数据,而不是保留应用缓冲区,直到发送数据被确认。默认值:1(启用)"
|
||||
}
|
||||
label {
|
||||
en: "Send buffering enabled"
|
||||
zh: "启用发送缓冲功能"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_pacing_enabled {
|
||||
desc {
|
||||
en: "Pace sending to avoid overfilling buffers on the path. Default: 1 (Enabled)"
|
||||
zh: "有节奏的发送,以避免路径上的缓冲区过度填充。默认值:1(已启用)"
|
||||
}
|
||||
label {
|
||||
en: "Pacing enabled"
|
||||
zh: "启用节奏发送"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_migration_enabled {
|
||||
desc {
|
||||
en: "Enable clients to migrate IP addresses and tuples. Requires a cooperative load-balancer, or no load-balancer. Default: 1 (Enabled)"
|
||||
zh: "开启客户端地址迁移功能。需要一个支持的负载平衡器,或者没有负载平衡器。默认值:1(已启用)"
|
||||
}
|
||||
label {
|
||||
en: "Migration enabled"
|
||||
zh: "启用地址迁移"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_datagram_receive_enabled {
|
||||
desc {
|
||||
en: "Advertise support for QUIC datagram extension. Reserve for the future. Default 0 (FALSE)"
|
||||
zh: "宣传对QUIC Datagram 扩展的支持。为将来保留。默认为0(FALSE)"
|
||||
}
|
||||
label {
|
||||
en: "Datagram receive enabled"
|
||||
zh: "启用 Datagram 接收"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_server_resumption_level {
|
||||
desc {
|
||||
en: "Controls resumption tickets and/or 0-RTT server support. Default: 0 (No resumption)"
|
||||
zh: "连接恢复 和/或 0-RTT 服务器支持。默认值:0(无恢复功能)"
|
||||
}
|
||||
label {
|
||||
en: "Server resumption level"
|
||||
zh: "服务端连接恢复支持"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_minimum_mtu {
|
||||
desc {
|
||||
en: "The minimum MTU supported by a connection. This will be used as the starting MTU. Default: 1248"
|
||||
zh: "一个连接所支持的最小MTU。这将被作为起始MTU使用。默认值:1248"
|
||||
}
|
||||
label {
|
||||
en: "Minimum MTU"
|
||||
zh: "最小 MTU"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_maximum_mtu {
|
||||
desc {
|
||||
en: "The maximum MTU supported by a connection. This will be the maximum probed value. Default: 1500"
|
||||
zh: "一个连接所支持的最大MTU。这将是最大的探测值。默认值:1500"
|
||||
}
|
||||
label {
|
||||
en: "Maximum MTU"
|
||||
zh: "最大 MTU"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_mtu_discovery_search_complete_timeout_us {
|
||||
desc {
|
||||
en: "The time in microseconds to wait before reattempting MTU probing if max was not reached. Default: 600000000"
|
||||
zh: "如果没有达到 max ,在重新尝试 MTU 探测之前要等待的时间,单位是微秒。默认值:600000000"
|
||||
}
|
||||
label {
|
||||
en: "MTU discovery search complete timeout us"
|
||||
zh: ""
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_mtu_discovery_missing_probe_count {
|
||||
desc {
|
||||
en: "The maximum number of stateless operations that may be queued on a binding at any one time. Default: 3"
|
||||
zh: "在任何时候都可以在一个绑定上排队的无状态操作的最大数量。默认值:3"
|
||||
}
|
||||
label {
|
||||
en: "MTU discovery missing probe count"
|
||||
zh: "MTU发现丢失的探针数量"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_max_binding_stateless_operations {
|
||||
desc {
|
||||
en: "The maximum number of stateless operations that may be queued on a binding at any one time. Default: 100"
|
||||
zh: "在任何时候可以在一个绑定上排队的无状态操作的最大数量。默认值:100"
|
||||
}
|
||||
label {
|
||||
en: "Max binding stateless operations"
|
||||
zh: "最大绑定无状态操作"
|
||||
}
|
||||
}
|
||||
|
||||
fields_mqtt_quic_listener_stateless_operation_expiration_ms {
|
||||
desc {
|
||||
en: "The time limit between operations for the same endpoint, in milliseconds. Default: 100"
|
||||
zh: "同一个对端的操作之间的时间限制,单位是毫秒。 默认:100"
|
||||
}
|
||||
label {
|
||||
en: "Stateless operation expiration ms"
|
||||
zh: "无状态操作过期 毫秒"
|
||||
}
|
||||
}
|
||||
|
||||
base_listener_max_connections {
|
||||
desc {
|
||||
en: """The maximum number of concurrent connections allowed by the listener."""
|
||||
|
|
|
@ -383,17 +383,18 @@ do_start_listener(quic, ListenerName, #{bind := Bind} = Opts) ->
|
|||
{keep_alive_interval_ms, maps:get(keep_alive_interval, Opts, 0)},
|
||||
{idle_timeout_ms, maps:get(idle_timeout, Opts, 0)},
|
||||
{handshake_idle_timeout_ms, maps:get(handshake_idle_timeout, Opts, 10000)},
|
||||
{server_resumption_level, 2},
|
||||
{server_resumption_level, maps:get(server_resumption_level, Opts, 2)},
|
||||
{verify, maps:get(verify, SSLOpts, verify_none)}
|
||||
] ++
|
||||
case maps:get(cacertfile, SSLOpts, undefined) of
|
||||
undefined -> [];
|
||||
CaCertFile -> [{cacertfile, binary_to_list(CaCertFile)}]
|
||||
end,
|
||||
end ++
|
||||
optional_quic_listener_opts(Opts),
|
||||
ConnectionOpts = #{
|
||||
conn_callback => emqx_quic_connection,
|
||||
peer_unidi_stream_count => 1,
|
||||
peer_bidi_stream_count => 10,
|
||||
peer_unidi_stream_count => maps:get(peer_unidi_stream_count, Opts, 1),
|
||||
peer_bidi_stream_count => maps:get(peer_bidi_stream_count, Opts, 10),
|
||||
zone => zone(Opts),
|
||||
listener => {quic, ListenerName},
|
||||
limiter => limiter(Opts)
|
||||
|
@ -726,3 +727,61 @@ get_ssl_options(Conf) ->
|
|||
error ->
|
||||
maps:get(<<"ssl_options">>, Conf, undefined)
|
||||
end.
|
||||
|
||||
%% @doc Get QUIC optional settings for low level tunings.
|
||||
%% @see quicer:quic_settings()
|
||||
-spec optional_quic_listener_opts(map()) -> proplists:proplist().
|
||||
optional_quic_listener_opts(Conf) when is_map(Conf) ->
|
||||
maps:to_list(
|
||||
maps:filter(
|
||||
fun(Name, _V) ->
|
||||
lists:member(
|
||||
Name,
|
||||
quic_listener_optional_settings()
|
||||
)
|
||||
end,
|
||||
Conf
|
||||
)
|
||||
).
|
||||
|
||||
-spec quic_listener_optional_settings() -> [atom()].
|
||||
quic_listener_optional_settings() ->
|
||||
[
|
||||
max_bytes_per_key,
|
||||
%% In conf schema we use handshake_idle_timeout
|
||||
handshake_idle_timeout_ms,
|
||||
%% In conf schema we use idle_timeout
|
||||
idle_timeout_ms,
|
||||
%% not use since we are server
|
||||
%% tls_client_max_send_buffer,
|
||||
tls_server_max_send_buffer,
|
||||
stream_recv_window_default,
|
||||
stream_recv_buffer_default,
|
||||
conn_flow_control_window,
|
||||
max_stateless_operations,
|
||||
initial_window_packets,
|
||||
send_idle_timeout_ms,
|
||||
initial_rtt_ms,
|
||||
max_ack_delay_ms,
|
||||
disconnect_timeout_ms,
|
||||
%% In conf schema, we use keep_alive_interval
|
||||
keep_alive_interval_ms,
|
||||
%% over written by conn opts
|
||||
peer_bidi_stream_count,
|
||||
%% over written by conn opts
|
||||
peer_unidi_stream_count,
|
||||
retry_memory_limit,
|
||||
load_balancing_mode,
|
||||
max_operations_per_drain,
|
||||
send_buffering_enabled,
|
||||
pacing_enabled,
|
||||
migration_enabled,
|
||||
datagram_receive_enabled,
|
||||
server_resumption_level,
|
||||
minimum_mtu,
|
||||
maximum_mtu,
|
||||
mtu_discovery_search_complete_timeout_us,
|
||||
mtu_discovery_missing_probe_count,
|
||||
max_binding_stateless_operations,
|
||||
stateless_operation_expiration_ms
|
||||
].
|
||||
|
|
|
@ -120,6 +120,9 @@
|
|||
|
||||
-elvis([{elvis_style, god_modules, disable}]).
|
||||
|
||||
-define(BIT(Bits), (1 bsl (Bits))).
|
||||
-define(MAX_UINT(Bits), (?BIT(Bits) - 1)).
|
||||
|
||||
namespace() -> broker.
|
||||
|
||||
tags() ->
|
||||
|
@ -862,6 +865,79 @@ fields("mqtt_quic_listener") ->
|
|||
}
|
||||
)},
|
||||
{"ciphers", ciphers_schema(quic)},
|
||||
|
||||
{"max_bytes_per_key",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(64),
|
||||
?DESC(fields_mqtt_quic_listener_max_bytes_per_key)
|
||||
)},
|
||||
{"handshake_idle_timeout_ms",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(64),
|
||||
?DESC(fields_mqtt_quic_listener_handshake_idle_timeout)
|
||||
)},
|
||||
{"tls_server_max_send_buffer",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(32),
|
||||
?DESC(fields_mqtt_quic_listener_tls_server_max_send_buffer)
|
||||
)},
|
||||
{"stream_recv_window_default",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(32),
|
||||
?DESC(fields_mqtt_quic_listener_stream_recv_window_default)
|
||||
)},
|
||||
{"stream_recv_buffer_default",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(32),
|
||||
?DESC(fields_mqtt_quic_listener_stream_recv_buffer_default)
|
||||
)},
|
||||
{"conn_flow_control_window",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(32),
|
||||
?DESC(fields_mqtt_quic_listener_conn_flow_control_window)
|
||||
)},
|
||||
{"max_stateless_operations",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(32),
|
||||
?DESC(fields_mqtt_quic_listener_max_stateless_operations)
|
||||
)},
|
||||
{"initial_window_packets",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(32),
|
||||
?DESC(fields_mqtt_quic_listener_initial_window_packets)
|
||||
)},
|
||||
{"send_idle_timeout_ms",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(32),
|
||||
?DESC(fields_mqtt_quic_listener_send_idle_timeout_ms)
|
||||
)},
|
||||
{"initial_rtt_ms",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(32),
|
||||
?DESC(fields_mqtt_quic_listener_initial_rtt_ms)
|
||||
)},
|
||||
{"max_ack_delay_ms",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(32),
|
||||
?DESC(fields_mqtt_quic_listener_max_ack_delay_ms)
|
||||
)},
|
||||
{"disconnect_timeout_ms",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(32),
|
||||
?DESC(fields_mqtt_quic_listener_disconnect_timeout_ms)
|
||||
)},
|
||||
{"idle_timeout",
|
||||
sc(
|
||||
duration_ms(),
|
||||
|
@ -870,6 +946,12 @@ fields("mqtt_quic_listener") ->
|
|||
desc => ?DESC(fields_mqtt_quic_listener_idle_timeout)
|
||||
}
|
||||
)},
|
||||
{"idle_timeout_ms",
|
||||
quic_lowlevel_settings_uint(
|
||||
0,
|
||||
?MAX_UINT(64),
|
||||
?DESC(fields_mqtt_quic_listener_idle_timeout_ms)
|
||||
)},
|
||||
{"handshake_idle_timeout",
|
||||
sc(
|
||||
duration_ms(),
|
||||
|
@ -878,6 +960,12 @@ fields("mqtt_quic_listener") ->
|
|||
desc => ?DESC(fields_mqtt_quic_listener_handshake_idle_timeout)
|
||||
}
|
||||
)},
|
||||
{"handshake_idle_timeout_ms",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(64),
|
||||
?DESC(fields_mqtt_quic_listener_handshake_idle_timeout_ms)
|
||||
)},
|
||||
{"keep_alive_interval",
|
||||
sc(
|
||||
duration_ms(),
|
||||
|
@ -886,6 +974,100 @@ fields("mqtt_quic_listener") ->
|
|||
desc => ?DESC(fields_mqtt_quic_listener_keep_alive_interval)
|
||||
}
|
||||
)},
|
||||
{"keep_alive_interval_ms",
|
||||
quic_lowlevel_settings_uint(
|
||||
0,
|
||||
?MAX_UINT(32),
|
||||
?DESC(fields_mqtt_quic_listener_keep_alive_interval_ms)
|
||||
)},
|
||||
{"peer_bidi_stream_count",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(16),
|
||||
?DESC(fields_mqtt_quic_listener_peer_bidi_stream_count)
|
||||
)},
|
||||
{"peer_unidi_stream_count",
|
||||
quic_lowlevel_settings_uint(
|
||||
0,
|
||||
?MAX_UINT(16),
|
||||
?DESC(fields_mqtt_quic_listener_peer_unidi_stream_count)
|
||||
)},
|
||||
{"retry_memory_limit",
|
||||
quic_lowlevel_settings_uint(
|
||||
0,
|
||||
?MAX_UINT(16),
|
||||
?DESC(fields_mqtt_quic_listener_retry_memory_limit)
|
||||
)},
|
||||
{"load_balancing_mode",
|
||||
quic_lowlevel_settings_uint(
|
||||
0,
|
||||
?MAX_UINT(16),
|
||||
?DESC(fields_mqtt_quic_listener_load_balancing_mode)
|
||||
)},
|
||||
{"max_operations_per_drain",
|
||||
quic_lowlevel_settings_uint(
|
||||
0,
|
||||
?MAX_UINT(8),
|
||||
?DESC(fields_mqtt_quic_listener_max_operations_per_drain)
|
||||
)},
|
||||
{"send_buffering_enabled",
|
||||
quic_feature_toggle(
|
||||
?DESC(fields_mqtt_quic_listener_send_buffering_enabled)
|
||||
)},
|
||||
{"pacing_enabled",
|
||||
quic_feature_toggle(
|
||||
?DESC(fields_mqtt_quic_listener_pacing_enabled)
|
||||
)},
|
||||
{"migration_enabled",
|
||||
quic_feature_toggle(
|
||||
?DESC(fields_mqtt_quic_listener_migration_enabled)
|
||||
)},
|
||||
{"datagram_receive_enabled",
|
||||
quic_feature_toggle(
|
||||
?DESC(fields_mqtt_quic_listener_datagram_receive_enabled)
|
||||
)},
|
||||
{"server_resumption_level",
|
||||
quic_lowlevel_settings_uint(
|
||||
0,
|
||||
?MAX_UINT(8),
|
||||
?DESC(fields_mqtt_quic_listener_server_resumption_level)
|
||||
)},
|
||||
{"minimum_mtu",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(16),
|
||||
?DESC(fields_mqtt_quic_listener_minimum_mtu)
|
||||
)},
|
||||
{"maximum_mtu",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(16),
|
||||
?DESC(fields_mqtt_quic_listener_maximum_mtu)
|
||||
)},
|
||||
{"mtu_discovery_search_complete_timeout_us",
|
||||
quic_lowlevel_settings_uint(
|
||||
0,
|
||||
?MAX_UINT(64),
|
||||
?DESC(fields_mqtt_quic_listener_mtu_discovery_search_complete_timeout_us)
|
||||
)},
|
||||
{"mtu_discovery_missing_probe_count",
|
||||
quic_lowlevel_settings_uint(
|
||||
1,
|
||||
?MAX_UINT(8),
|
||||
?DESC(fields_mqtt_quic_listener_mtu_discovery_missing_probe_count)
|
||||
)},
|
||||
{"max_binding_stateless_operations",
|
||||
quic_lowlevel_settings_uint(
|
||||
0,
|
||||
?MAX_UINT(16),
|
||||
?DESC(fields_mqtt_quic_listener_max_binding_stateless_operations)
|
||||
)},
|
||||
{"stateless_operation_expiration_ms",
|
||||
quic_lowlevel_settings_uint(
|
||||
0,
|
||||
?MAX_UINT(16),
|
||||
?DESC(fields_mqtt_quic_listener_stateless_operation_expiration_ms)
|
||||
)},
|
||||
{"ssl_options",
|
||||
sc(
|
||||
ref("listener_quic_ssl_opts"),
|
||||
|
@ -2638,3 +2820,30 @@ parse_port(Port) ->
|
|||
_:_ ->
|
||||
throw("bad_port_number")
|
||||
end.
|
||||
|
||||
quic_feature_toggle(Desc) ->
|
||||
sc(
|
||||
%% true, false are for user facing
|
||||
%% 0, 1 are for internal represtation
|
||||
typerefl:alias("boolean", typerefl:union([true, false, 0, 1])),
|
||||
#{
|
||||
desc => Desc,
|
||||
hidden => true,
|
||||
required => false,
|
||||
converter => fun
|
||||
(true) -> 1;
|
||||
(false) -> 0;
|
||||
(Other) -> Other
|
||||
end
|
||||
}
|
||||
).
|
||||
|
||||
quic_lowlevel_settings_uint(Low, High, Desc) ->
|
||||
sc(
|
||||
range(Low, High),
|
||||
#{
|
||||
required => false,
|
||||
hidden => true,
|
||||
desc => Desc
|
||||
}
|
||||
).
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
client_ssl_twoway/1,
|
||||
ensure_mnesia_stopped/0,
|
||||
ensure_quic_listener/2,
|
||||
ensure_quic_listener/3,
|
||||
is_all_tcp_servers_available/1,
|
||||
is_tcp_server_available/2,
|
||||
is_tcp_server_available/3,
|
||||
|
@ -511,6 +512,9 @@ ensure_dashboard_listeners_started(_App) ->
|
|||
|
||||
-spec ensure_quic_listener(Name :: atom(), UdpPort :: inet:port_number()) -> ok.
|
||||
ensure_quic_listener(Name, UdpPort) ->
|
||||
ensure_quic_listener(Name, UdpPort, #{}).
|
||||
-spec ensure_quic_listener(Name :: atom(), UdpPort :: inet:port_number(), map()) -> ok.
|
||||
ensure_quic_listener(Name, UdpPort, ExtraSettings) ->
|
||||
application:ensure_all_started(quicer),
|
||||
Conf = #{
|
||||
acceptors => 16,
|
||||
|
@ -533,7 +537,7 @@ ensure_quic_listener(Name, UdpPort) ->
|
|||
mountpoint => <<>>,
|
||||
zone => default
|
||||
},
|
||||
emqx_config:put([listeners, quic, Name], Conf),
|
||||
emqx_config:put([listeners, quic, Name], maps:merge(Conf, ExtraSettings)),
|
||||
case emqx_listeners:start_listener(quic, Name, Conf) of
|
||||
ok -> ok;
|
||||
{error, {already_started, _Pid}} -> ok
|
||||
|
|
|
@ -32,7 +32,8 @@ all() ->
|
|||
[
|
||||
{group, mstream},
|
||||
{group, shutdown},
|
||||
{group, misc}
|
||||
{group, misc},
|
||||
t_listener_with_lowlevel_settings
|
||||
].
|
||||
|
||||
groups() ->
|
||||
|
@ -1892,6 +1893,60 @@ t_multi_streams_sub_0_rtt_stream_data_cont(Config) ->
|
|||
ok = emqtt:disconnect(C),
|
||||
ok = emqtt:disconnect(C0).
|
||||
|
||||
t_listener_with_lowlevel_settings(_Config) ->
|
||||
LPort = 24567,
|
||||
LowLevelTunings = #{
|
||||
max_bytes_per_key => 274877906,
|
||||
%% In conf schema we use handshake_idle_timeout
|
||||
handshake_idle_timeout_ms => 2000,
|
||||
%% In conf schema we use idle_timeout
|
||||
idle_timeout_ms => 20000,
|
||||
%% not use since we are server
|
||||
%% tls_client_max_send_buffer,
|
||||
tls_server_max_send_buffer => 10240,
|
||||
stream_recv_window_default => 1024,
|
||||
stream_recv_buffer_default => 1024,
|
||||
conn_flow_control_window => 1024,
|
||||
max_stateless_operations => 16,
|
||||
initial_window_packets => 1300,
|
||||
send_idle_timeout_ms => 12000,
|
||||
initial_rtt_ms => 300,
|
||||
max_ack_delay_ms => 6000,
|
||||
disconnect_timeout_ms => 60000,
|
||||
%% In conf schema, we use keep_alive_interval
|
||||
keep_alive_interval_ms => 12000,
|
||||
%% over written by conn opts
|
||||
peer_bidi_stream_count => 100,
|
||||
%% over written by conn opts
|
||||
peer_unidi_stream_count => 100,
|
||||
retry_memory_limit => 640,
|
||||
load_balancing_mode => 1,
|
||||
max_operations_per_drain => 32,
|
||||
send_buffering_enabled => 1,
|
||||
pacing_enabled => 0,
|
||||
migration_enabled => 0,
|
||||
datagram_receive_enabled => 1,
|
||||
server_resumption_level => 0,
|
||||
minimum_mtu => 1250,
|
||||
maximum_mtu => 1600,
|
||||
mtu_discovery_search_complete_timeout_us => 500000000,
|
||||
mtu_discovery_missing_probe_count => 6,
|
||||
max_binding_stateless_operations => 200,
|
||||
stateless_operation_expiration_ms => 200
|
||||
},
|
||||
?assertEqual(
|
||||
ok, emqx_common_test_helpers:ensure_quic_listener(?FUNCTION_NAME, LPort, LowLevelTunings)
|
||||
),
|
||||
timer:sleep(1000),
|
||||
{ok, C} = emqtt:start_link([{proto_ver, v5}, {port, LPort}]),
|
||||
{ok, _} = emqtt:quic_connect(C),
|
||||
{ok, _, _} = emqtt:subscribe(C, <<"test/1/2">>, qos2),
|
||||
{ok, _, [_SubQos]} = emqtt:subscribe_via(C, {new_data_stream, []}, #{}, [
|
||||
{<<"test/1/3">>, [{qos, 2}]}
|
||||
]),
|
||||
ok = emqtt:disconnect(C),
|
||||
emqx_listeners:stop_listener(emqx_listeners:listener_id(quic, ?FUNCTION_NAME)).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Helper functions
|
||||
%%--------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Add low level tuning settings for QUIC listeners.
|
|
@ -0,0 +1 @@
|
|||
为 QUIC 侦听器添加更多底层调优选项。
|
Loading…
Reference in New Issue