From 3955d98aa2cec85c50a1b0a7e0e55a0f78e9211d Mon Sep 17 00:00:00 2001 From: Toby Date: Fri, 30 Apr 2021 21:29:18 -0700 Subject: [PATCH] Better default params to reduce flow control blocks & add README for optimizing for extreme transfer speeds --- README.md | 19 +++++++++++++++++-- README.zh.md | 17 +++++++++++++++-- cmd/client.go | 20 ++++++++++++-------- cmd/config.go | 6 +++--- cmd/server.go | 22 +++++++++++++--------- 5 files changed, 60 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index b0635e7..f9edc25 100644 --- a/README.md +++ b/README.md @@ -162,7 +162,7 @@ Proxy Server: AWS US West Oregon (us-west-2) } }, "prometheus_listen": ":8080", // Prometheus HTTP metrics server listen address (at /metrics) - "recv_window_conn": 33554432, // QUIC stream receive window + "recv_window_conn": 15728640, // QUIC stream receive window "recv_window_client": 67108864, // QUIC connection receive window "max_conn_client": 4096 // Max concurrent connections per client } @@ -273,7 +273,7 @@ hysteria_traffic_uplink_bytes_total{auth="aGFja2VyISE="} 37452 "auth_str": "yubiyubi", // Authentication payload in string, mutually exclusive with the option above "insecure": false, // Ignore all certificate errors "ca": "my.ca", // Custom CA file - "recv_window_conn": 33554432, // QUIC stream receive window + "recv_window_conn": 15728640, // QUIC stream receive window "recv_window": 67108864 // QUIC connection receive window } ``` @@ -286,6 +286,21 @@ References: - https://www.kernel.org/doc/Documentation/networking/tproxy.txt - https://powerdns.org/tproxydoc/tproxy.md.html +## Optimizing for extreme transfer speeds + +If you want to use Hysteria for very high speed transfers (e.g. 10GE, 1G+ over inter-country long fat pipes), consider +increasing your system's UDP receive buffer size. + +```shell +sysctl -w net.core.rmem_max=4000000 +``` + +This would increase the buffer size to roughly 4 MB on Linux. + +You may also need to increase `recv_window_conn` and `recv_window` (`recv_window_client` on server side) to make sure +they are at least no less than the bandwidth-delay product. For example, if you want to achieve a transfer speed of 500 +MB/s on a line with an RTT of 200 ms, you need a minimum receive window size of 100 MB (500*0.2). + ## ACL [ACL File Format](ACL.md) diff --git a/README.zh.md b/README.zh.md index 33c4e9d..79a4946 100644 --- a/README.zh.md +++ b/README.zh.md @@ -150,7 +150,7 @@ Hysteria 是专门针对恶劣网络环境进行优化的 TCP/UDP 转发和代 } }, "prometheus_listen": ":8080", // Prometheus 统计接口监听地址 (在 /metrics) - "recv_window_conn": 33554432, // QUIC stream receive window + "recv_window_conn": 15728640, // QUIC stream receive window "recv_window_client": 67108864, // QUIC connection receive window "max_conn_client": 4096 // 单客户端最大活跃连接数 } @@ -260,7 +260,7 @@ hysteria_traffic_uplink_bytes_total{auth="aGFja2VyISE="} 37452 "auth_str": "yubiyubi", // 字符串验证密钥,和上面的选项二选一 "insecure": false, // 忽略一切证书错误 "ca": "my.ca", // 自定义 CA - "recv_window_conn": 33554432, // QUIC stream receive window + "recv_window_conn": 15728640, // QUIC stream receive window "recv_window": 67108864 // QUIC connection receive window } ``` @@ -273,6 +273,19 @@ TPROXY 模式 (`tproxy_tcp` 和 `tproxy_udp`) 只在 Linux 下可用。 - https://www.kernel.org/doc/Documentation/networking/tproxy.txt - https://powerdns.org/tproxydoc/tproxy.md.html +## 针对超高传速度进行优化 + +如果要用 Hysteria 进行极高速度的传输 (如内网超过 10G 或高延迟跨国超过 1G),请增加系统的 UDP receive buffer 大小。 + +```shell +sysctl -w net.core.rmem_max=4000000 +``` + +这个命令会在 Linux 下将 buffer 大小提升到 4 MB 左右。 + +你可能还需要提高 `recv_window_conn` 和 `recv_window` (服务器端是 `recv_window_client`) 以确保它们至少不低于带宽-延迟的乘积。 +比如如果想在一条 RTT 200ms 的线路上达到 500 MB/s 的速度,receive window 至少需要 100 MB (500*0.2) + ## 关于 ACL [ACL 文件格式](ACL.zh.md) diff --git a/cmd/client.go b/cmd/client.go index 1949926..c57c14e 100644 --- a/cmd/client.go +++ b/cmd/client.go @@ -49,16 +49,20 @@ func client(config *clientConfig) { } // QUIC config quicConfig := &quic.Config{ - MaxStreamReceiveWindow: config.ReceiveWindowConn, - MaxConnectionReceiveWindow: config.ReceiveWindow, - KeepAlive: true, - EnableDatagrams: true, + InitialStreamReceiveWindow: config.ReceiveWindowConn, + MaxStreamReceiveWindow: config.ReceiveWindowConn, + InitialConnectionReceiveWindow: config.ReceiveWindow, + MaxConnectionReceiveWindow: config.ReceiveWindow, + KeepAlive: true, + EnableDatagrams: true, } - if quicConfig.MaxStreamReceiveWindow == 0 { - quicConfig.MaxStreamReceiveWindow = DefaultMaxReceiveStreamFlowControlWindow + if config.ReceiveWindowConn == 0 { + quicConfig.InitialStreamReceiveWindow = DefaultStreamReceiveWindow + quicConfig.MaxStreamReceiveWindow = DefaultStreamReceiveWindow } - if quicConfig.MaxConnectionReceiveWindow == 0 { - quicConfig.MaxConnectionReceiveWindow = DefaultMaxReceiveConnectionFlowControlWindow + if config.ReceiveWindow == 0 { + quicConfig.InitialConnectionReceiveWindow = DefaultConnectionReceiveWindow + quicConfig.MaxConnectionReceiveWindow = DefaultConnectionReceiveWindow } // Auth var auth []byte diff --git a/cmd/config.go b/cmd/config.go index 640c460..f448edc 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -9,9 +9,9 @@ import ( const ( mbpsToBps = 125000 - DefaultMaxReceiveStreamFlowControlWindow = 33554432 - DefaultMaxReceiveConnectionFlowControlWindow = 67108864 - DefaultMaxIncomingStreams = 1024 + DefaultStreamReceiveWindow = 15728640 // 15 MB/s + DefaultConnectionReceiveWindow = 67108864 // 64 MB/s + DefaultMaxIncomingStreams = 1024 tlsProtocolName = "hysteria" ) diff --git a/cmd/server.go b/cmd/server.go index a533b21..c237620 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -55,17 +55,21 @@ func server(config *serverConfig) { } // QUIC config quicConfig := &quic.Config{ - MaxStreamReceiveWindow: config.ReceiveWindowConn, - MaxConnectionReceiveWindow: config.ReceiveWindowClient, - MaxIncomingStreams: int64(config.MaxConnClient), - KeepAlive: true, - EnableDatagrams: true, + InitialStreamReceiveWindow: config.ReceiveWindowConn, + MaxStreamReceiveWindow: config.ReceiveWindowConn, + InitialConnectionReceiveWindow: config.ReceiveWindowClient, + MaxConnectionReceiveWindow: config.ReceiveWindowClient, + MaxIncomingStreams: int64(config.MaxConnClient), + KeepAlive: true, + EnableDatagrams: true, } - if quicConfig.MaxStreamReceiveWindow == 0 { - quicConfig.MaxStreamReceiveWindow = DefaultMaxReceiveStreamFlowControlWindow + if config.ReceiveWindowConn == 0 { + quicConfig.InitialStreamReceiveWindow = DefaultStreamReceiveWindow + quicConfig.MaxStreamReceiveWindow = DefaultStreamReceiveWindow } - if quicConfig.MaxConnectionReceiveWindow == 0 { - quicConfig.MaxConnectionReceiveWindow = DefaultMaxReceiveConnectionFlowControlWindow + if config.ReceiveWindowClient == 0 { + quicConfig.InitialConnectionReceiveWindow = DefaultConnectionReceiveWindow + quicConfig.MaxConnectionReceiveWindow = DefaultConnectionReceiveWindow } if quicConfig.MaxIncomingStreams == 0 { quicConfig.MaxIncomingStreams = DefaultMaxIncomingStreams