mirror of
https://github.com/XTLS/REALITY.git
synced 2025-08-31 02:45:31 +00:00
Fix the misspelling of burst
This commit is contained in:
parent
1b088adc09
commit
5ccbfeb2d4
164
README.en.md
164
README.en.md
@ -3,7 +3,7 @@
|
||||
### THE NEXT FUTURE
|
||||
|
||||
Server side implementation of REALITY protocol, a fork of package tls in latest [Go](https://github.com/golang/go/commits/master/src/crypto/tls).
|
||||
For client side, please follow https://github.com/XTLS/Xray-core/blob/main/transport/internet/reality/reality.go.
|
||||
For client side, please follow https://github.com/XTLS/Xray-core/blob/main/transport/internet/reality/reality.go.
|
||||
|
||||
TODO List: TODO
|
||||
|
||||
@ -13,58 +13,61 @@ TODO List: TODO
|
||||
|
||||
```json5
|
||||
{
|
||||
"inbounds": [ // Server Inbound Configuration
|
||||
{
|
||||
"listen": "0.0.0.0",
|
||||
"port": 443,
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "", // Required, execute ./xray uuid to generate, or a string of 1-30 characters
|
||||
"flow": "xtls-rprx-vision" // Optional, if any, client must enable XTLS
|
||||
}
|
||||
],
|
||||
"decryption": "none"
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"show": false, // Optional, if true, output debugging information
|
||||
"dest": "example.com:443", // Required, the format is the same as the dest of VLESS fallbacks
|
||||
"xver": 0, // Optional, the format is the same as xver of VLESS fallbacks
|
||||
"serverNames": [ // Required, the acceptable serverName list, does not support * wildcards for now
|
||||
"example.com",
|
||||
"www.example.com"
|
||||
],
|
||||
"privateKey": "", // Required, execute ./xray x25519 to generate
|
||||
"minClientVer": "", // Optional, minimum client Xray version, format is x.y.z
|
||||
"maxClientVer": "", // Optional, the highest version of client Xray, the format is x.y.z
|
||||
"maxTimeDiff": 0, // Optional, the maximum time difference allowed, in milliseconds
|
||||
"shortIds": [ // Required, the acceptable shortId list, which can be used to distinguish different clients
|
||||
"", // If there is this item, the client shortId can be empty
|
||||
"0123456789abcdef" // 0 to f, the length is a multiple of 2, the maximum length is 16
|
||||
],
|
||||
// The six limit below are optional for rate limiting falling REALITY connections. Default are 0 means disabled
|
||||
// WARNING: Enabling rate limiting may create detectable patterns for GFW!
|
||||
// If you're a GUI/panel/one-click script developer, RANDOMIZE these parameters!
|
||||
"limitUploadRate": 0, // Base upload speed (bytes/s)
|
||||
"limitUploadBrust": 0, // Upload burst capacity (bytes)
|
||||
"limitUploadAfter": 0, // Start upload throttling after (bytes)
|
||||
"limitDownloadRate": 0, // Base download speed (bytes/s)
|
||||
"limitDownloadBrust": 0, // Download burst capacity (bytes)
|
||||
"limitDownloadAfter": 0 // Start download throttling after (bytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
inbounds: [
|
||||
// Server Inbound Configuration
|
||||
{
|
||||
listen: "0.0.0.0",
|
||||
port: 443,
|
||||
protocol: "vless",
|
||||
settings: {
|
||||
clients: [
|
||||
{
|
||||
id: "", // Required, execute ./xray uuid to generate, or a string of 1-30 characters
|
||||
flow: "xtls-rprx-vision", // Optional, if any, client must enable XTLS
|
||||
},
|
||||
],
|
||||
decryption: "none",
|
||||
},
|
||||
streamSettings: {
|
||||
network: "tcp",
|
||||
security: "reality",
|
||||
realitySettings: {
|
||||
show: false, // Optional, if true, output debugging information
|
||||
dest: "example.com:443", // Required, the format is the same as the dest of VLESS fallbacks
|
||||
xver: 0, // Optional, the format is the same as xver of VLESS fallbacks
|
||||
serverNames: [
|
||||
// Required, the acceptable serverName list, does not support * wildcards for now
|
||||
"example.com",
|
||||
"www.example.com",
|
||||
],
|
||||
privateKey: "", // Required, execute ./xray x25519 to generate
|
||||
minClientVer: "", // Optional, minimum client Xray version, format is x.y.z
|
||||
maxClientVer: "", // Optional, the highest version of client Xray, the format is x.y.z
|
||||
maxTimeDiff: 0, // Optional, the maximum time difference allowed, in milliseconds
|
||||
shortIds: [
|
||||
// Required, the acceptable shortId list, which can be used to distinguish different clients
|
||||
"", // If there is this item, the client shortId can be empty
|
||||
"0123456789abcdef", // 0 to f, the length is a multiple of 2, the maximum length is 16
|
||||
],
|
||||
// The six limit below are optional for rate limiting falling REALITY connections. Default are 0 means disabled
|
||||
// WARNING: Enabling rate limiting may create detectable patterns for GFW!
|
||||
// If you're a GUI/panel/one-click script developer, RANDOMIZE these parameters!
|
||||
limitUploadRate: 0, // Base upload speed (bytes/s)
|
||||
limitUploadBurst: 0, // Upload burst capacity (bytes)
|
||||
limitUploadAfter: 0, // Start upload throttling after (bytes)
|
||||
limitDownloadRate: 0, // Base download speed (bytes/s)
|
||||
limitDownloadBurst: 0, // Download burst capacity (bytes)
|
||||
limitDownloadAfter: 0, // Start download throttling after (bytes)
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
REALITY is intented to replace the use of TLS, it can **eliminate the detectable TLS fingerprint on the server side**, while still maintain the forward secrecy, etc. **Guard against the certificate chain attack, thus its security exceeds conventional TLS**
|
||||
**REALITY can point to other people's websites**, no need to buy domain names, configure TLS server, more convenient to deploy a proxy service. It **achieves full real TLS that is undistingwishable with the specified SNI to the middleman**
|
||||
|
||||
|
||||
For general proxy purposes, the minimum standard of the target website: **Websites out of China's GFW, support TLSv1.3 and H2, the domain name is not used for redirection** (the main domain name may be used to redirect to www)
|
||||
Bonus points: target website IP reside closer to proxy IP (looks more reasonable, and lower latency), handshake messages after Server Hello are encrypted together (such as dl.google.com), OCSP Stapling
|
||||
Configuration bonus items: **Block the proxy traffic back to China, TCP/80, UDP/443 are also forwarded to target** (REALITY behaves like port forwarding to the observer, the target IP may be better if it is an uncommon choice among REALITY users)
|
||||
@ -74,38 +77,39 @@ The next main goal of REALITY is "**pre-built mode**", that is, to collect and b
|
||||
|
||||
```json5
|
||||
{
|
||||
"outbounds": [ // Client outbound configuration
|
||||
{
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"vnext": [
|
||||
{
|
||||
"address": "", // The domain name or IP of the server
|
||||
"port": 443,
|
||||
"users": [
|
||||
{
|
||||
"id": "", // consistent with the server
|
||||
"flow": "xtls-rprx-vision", // consistent with the server
|
||||
"encryption": "none"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"show": false, // Optional, if true, output debugging information
|
||||
"fingerprint": "chrome", // Required, use uTLS library to emulate client TLS fingerprint
|
||||
"serverName": "", // One of the server serverNames
|
||||
"publicKey": "", // The public key corresponding to the private key of the server
|
||||
"shortId": "", // One of the server shortIds
|
||||
"spiderX": "" // The initial path and parameters of the crawler, recommended to be different for each client
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
outbounds: [
|
||||
// Client outbound configuration
|
||||
{
|
||||
protocol: "vless",
|
||||
settings: {
|
||||
vnext: [
|
||||
{
|
||||
address: "", // The domain name or IP of the server
|
||||
port: 443,
|
||||
users: [
|
||||
{
|
||||
id: "", // consistent with the server
|
||||
flow: "xtls-rprx-vision", // consistent with the server
|
||||
encryption: "none",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
streamSettings: {
|
||||
network: "tcp",
|
||||
security: "reality",
|
||||
realitySettings: {
|
||||
show: false, // Optional, if true, output debugging information
|
||||
fingerprint: "chrome", // Required, use uTLS library to emulate client TLS fingerprint
|
||||
serverName: "", // One of the server serverNames
|
||||
publicKey: "", // The public key corresponding to the private key of the server
|
||||
shortId: "", // One of the server shortIds
|
||||
spiderX: "", // The initial path and parameters of the crawler, recommended to be different for each client
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
|
174
README.md
174
README.md
@ -3,7 +3,7 @@
|
||||
### THE NEXT FUTURE
|
||||
|
||||
Server side implementation of REALITY protocol, a fork of package tls in latest [Go](https://github.com/golang/go/commits/master/src/crypto/tls).
|
||||
For client side, please follow https://github.com/XTLS/Xray-core/blob/main/transport/internet/reality/reality.go.
|
||||
For client side, please follow https://github.com/XTLS/Xray-core/blob/main/transport/internet/reality/reality.go.
|
||||
|
||||
TODO List: TODO
|
||||
|
||||
@ -13,98 +13,102 @@ TODO List: TODO
|
||||
|
||||
```json5
|
||||
{
|
||||
"inbounds": [ // 服务端入站配置
|
||||
{
|
||||
"listen": "0.0.0.0",
|
||||
"port": 443,
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"clients": [
|
||||
{
|
||||
"id": "", // 必填,执行 ./xray uuid 生成,或 1-30 字节的字符串
|
||||
"flow": "xtls-rprx-vision" // 选填,若有,客户端必须启用 XTLS
|
||||
}
|
||||
],
|
||||
"decryption": "none"
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"show": false, // 选填,若为 true,输出调试信息
|
||||
"dest": "example.com:443", // 必填,格式同 VLESS fallbacks 的 dest
|
||||
"xver": 0, // 选填,格式同 VLESS fallbacks 的 xver
|
||||
"serverNames": [ // 必填,客户端可用的 serverName 列表,暂不支持 * 通配符
|
||||
"example.com",
|
||||
"www.example.com"
|
||||
],
|
||||
"privateKey": "", // 必填,执行 ./xray x25519 生成
|
||||
"minClientVer": "", // 选填,客户端 Xray 最低版本,格式为 x.y.z
|
||||
"maxClientVer": "", // 选填,客户端 Xray 最高版本,格式为 x.y.z
|
||||
"maxTimeDiff": 0, // 选填,允许的最大时间差,单位为毫秒
|
||||
"shortIds": [ // 必填,客户端可用的 shortId 列表,可用于区分不同的客户端
|
||||
"", // 若有此项,客户端 shortId 可为空
|
||||
"0123456789abcdef" // 0 到 f,长度为 2 的倍数,长度上限为 16
|
||||
],
|
||||
// 下列六个 limit 为选填,可对回落的 REALITY 连接限速。默认为 0 即不启用
|
||||
// 警告:启用限速可能会引入新的特征被GFW探测到!如果您是GUI/面板/一键脚本开发者,请务必让这些参数随机化!
|
||||
"limitUploadRate": 0, // 上行基准速率 (字节/秒)
|
||||
"limitUploadBrust": 0, // 上行突发速率 (字节/秒)
|
||||
"limitUploadAfter": 0, // 上行指定字节后开始限速
|
||||
"limitDownloadRate": 0, // 下行基准速率 (字节/秒)
|
||||
"limitDownloadBrust": 0, // 下行突发速率 (字节/秒)
|
||||
"limitDownloadAfter": 0 // 下行指定字节后开始限速
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
inbounds: [
|
||||
// 服务端入站配置
|
||||
{
|
||||
listen: "0.0.0.0",
|
||||
port: 443,
|
||||
protocol: "vless",
|
||||
settings: {
|
||||
clients: [
|
||||
{
|
||||
id: "", // 必填,执行 ./xray uuid 生成,或 1-30 字节的字符串
|
||||
flow: "xtls-rprx-vision", // 选填,若有,客户端必须启用 XTLS
|
||||
},
|
||||
],
|
||||
decryption: "none",
|
||||
},
|
||||
streamSettings: {
|
||||
network: "tcp",
|
||||
security: "reality",
|
||||
realitySettings: {
|
||||
show: false, // 选填,若为 true,输出调试信息
|
||||
dest: "example.com:443", // 必填,格式同 VLESS fallbacks 的 dest
|
||||
xver: 0, // 选填,格式同 VLESS fallbacks 的 xver
|
||||
serverNames: [
|
||||
// 必填,客户端可用的 serverName 列表,暂不支持 * 通配符
|
||||
"example.com",
|
||||
"www.example.com",
|
||||
],
|
||||
privateKey: "", // 必填,执行 ./xray x25519 生成
|
||||
minClientVer: "", // 选填,客户端 Xray 最低版本,格式为 x.y.z
|
||||
maxClientVer: "", // 选填,客户端 Xray 最高版本,格式为 x.y.z
|
||||
maxTimeDiff: 0, // 选填,允许的最大时间差,单位为毫秒
|
||||
shortIds: [
|
||||
// 必填,客户端可用的 shortId 列表,可用于区分不同的客户端
|
||||
"", // 若有此项,客户端 shortId 可为空
|
||||
"0123456789abcdef", // 0 到 f,长度为 2 的倍数,长度上限为 16
|
||||
],
|
||||
// 下列六个 limit 为选填,可对回落的 REALITY 连接限速。默认为 0 即不启用
|
||||
// 警告:启用限速可能会引入新的特征被GFW探测到!如果您是GUI/面板/一键脚本开发者,请务必让这些参数随机化!
|
||||
limitUploadRate: 0, // 上行基准速率 (字节/秒)
|
||||
limitUploadBurst: 0, // 上行突发速率 (字节/秒)
|
||||
limitUploadAfter: 0, // 上行指定字节后开始限速
|
||||
limitDownloadRate: 0, // 下行基准速率 (字节/秒)
|
||||
limitDownloadBurst: 0, // 下行突发速率 (字节/秒)
|
||||
limitDownloadAfter: 0, // 下行指定字节后开始限速
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
若用 REALITY 取代 TLS,**可消除服务端 TLS 指纹特征**,仍有前向保密性等,**且证书链攻击无效,安全性超越常规 TLS**
|
||||
**可以指向别人的网站**,无需自己买域名、配置 TLS 服务端,更方便,**实现向中间人呈现指定 SNI 的全程真实 TLS**
|
||||
若用 REALITY 取代 TLS,**可消除服务端 TLS 指纹特征**,仍有前向保密性等,**且证书链攻击无效,安全性超越常规 TLS**
|
||||
**可以指向别人的网站**,无需自己买域名、配置 TLS 服务端,更方便,**实现向中间人呈现指定 SNI 的全程真实 TLS**
|
||||
|
||||
通常代理用途,目标网站最低标准:**国外网站,支持 TLSv1.3 与 H2,域名非跳转用**(主域名可能被用于跳转到 www)
|
||||
加分项:IP 相近(更像,且延迟低),Server Hello 后的握手消息一起加密(如 dl.google.com),有 OCSP Stapling
|
||||
配置加分项:**禁回国流量,TCP/80、UDP/443 也转发**(REALITY 对外表现即为端口转发,目标 IP 冷门或许更好)
|
||||
通常代理用途,目标网站最低标准:**国外网站,支持 TLSv1.3 与 H2,域名非跳转用**(主域名可能被用于跳转到 www)
|
||||
加分项:IP 相近(更像,且延迟低),Server Hello 后的握手消息一起加密(如 dl.google.com),有 OCSP Stapling
|
||||
配置加分项:**禁回国流量,TCP/80、UDP/443 也转发**(REALITY 对外表现即为端口转发,目标 IP 冷门或许更好)
|
||||
|
||||
**REALITY 也可以搭配 XTLS 以外的代理协议使用**,但不建议这样做,因为它们存在明显且已被针对的 TLS in TLS 特征
|
||||
REALITY 的下一个主要目标是“**预先构建模式**”,即提前采集目标网站特征,XTLS 的下一个主要目标是 **0-RTT**
|
||||
**REALITY 也可以搭配 XTLS 以外的代理协议使用**,但不建议这样做,因为它们存在明显且已被针对的 TLS in TLS 特征
|
||||
REALITY 的下一个主要目标是“**预先构建模式**”,即提前采集目标网站特征,XTLS 的下一个主要目标是 **0-RTT**
|
||||
|
||||
```json5
|
||||
{
|
||||
"outbounds": [ // 客户端出站配置
|
||||
{
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"vnext": [
|
||||
{
|
||||
"address": "", // 服务端的域名或 IP
|
||||
"port": 443,
|
||||
"users": [
|
||||
{
|
||||
"id": "", // 与服务端一致
|
||||
"flow": "xtls-rprx-vision", // 与服务端一致
|
||||
"encryption": "none"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"show": false, // 选填,若为 true,输出调试信息
|
||||
"fingerprint": "chrome", // 必填,使用 uTLS 库模拟客户端 TLS 指纹
|
||||
"serverName": "", // 服务端 serverNames 之一
|
||||
"publicKey": "", // 服务端私钥对应的公钥
|
||||
"shortId": "", // 服务端 shortIds 之一
|
||||
"spiderX": "" // 爬虫初始路径与参数,建议每个客户端不同
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
outbounds: [
|
||||
// 客户端出站配置
|
||||
{
|
||||
protocol: "vless",
|
||||
settings: {
|
||||
vnext: [
|
||||
{
|
||||
address: "", // 服务端的域名或 IP
|
||||
port: 443,
|
||||
users: [
|
||||
{
|
||||
id: "", // 与服务端一致
|
||||
flow: "xtls-rprx-vision", // 与服务端一致
|
||||
encryption: "none",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
streamSettings: {
|
||||
network: "tcp",
|
||||
security: "reality",
|
||||
realitySettings: {
|
||||
show: false, // 选填,若为 true,输出调试信息
|
||||
fingerprint: "chrome", // 必填,使用 uTLS 库模拟客户端 TLS 指纹
|
||||
serverName: "", // 服务端 serverNames 之一
|
||||
publicKey: "", // 服务端私钥对应的公钥
|
||||
shortId: "", // 服务端 shortIds 之一
|
||||
spiderX: "", // 爬虫初始路径与参数,建议每个客户端不同
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
|
11
common.go
11
common.go
@ -557,10 +557,10 @@ type Config struct {
|
||||
ShortIds map[[8]byte]bool
|
||||
|
||||
LimitUploadRate float64
|
||||
LimitUploadBrust int64
|
||||
LimitUploadBurst int64
|
||||
LimitUploadAfter int64
|
||||
LimitDownloadRate float64
|
||||
LimitDownloadBrust int64
|
||||
LimitDownloadBurst int64
|
||||
LimitDownloadAfter int64
|
||||
|
||||
// Rand provides the source of entropy for nonces and RSA blinding.
|
||||
@ -920,7 +920,6 @@ type EncryptedClientHelloKey struct {
|
||||
SendAsRetry bool
|
||||
}
|
||||
|
||||
|
||||
const (
|
||||
// ticketKeyLifetime is how long a ticket key remains valid and can be used to
|
||||
// resume a client connection.
|
||||
@ -979,10 +978,10 @@ func (c *Config) Clone() *Config {
|
||||
MaxTimeDiff: c.MaxTimeDiff,
|
||||
ShortIds: c.ShortIds,
|
||||
LimitUploadRate: c.LimitUploadRate,
|
||||
LimitUploadBrust: c.LimitUploadBrust,
|
||||
LimitUploadBurst: c.LimitUploadBurst,
|
||||
LimitUploadAfter: c.LimitUploadAfter,
|
||||
LimitDownloadRate: c.LimitDownloadRate,
|
||||
LimitDownloadBrust: c.LimitDownloadBrust,
|
||||
LimitDownloadBurst: c.LimitDownloadBurst,
|
||||
LimitDownloadAfter: c.LimitDownloadAfter,
|
||||
Rand: c.Rand,
|
||||
Time: c.Time,
|
||||
@ -1806,4 +1805,4 @@ func fipsAllowChain(chain []*x509.Certificate) bool {
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
18
tls.go
18
tls.go
@ -247,14 +247,14 @@ func Server(ctx context.Context, conn net.Conn, config *Config) (*Conn, error) {
|
||||
if config.Show && hs.clientHello != nil {
|
||||
fmt.Printf("REALITY remoteAddr: %v\tforwarded SNI: %v\n", remoteAddr, hs.clientHello.serverName)
|
||||
}
|
||||
if config.LimitUploadRate == 0 || config.LimitUploadBrust == 0 {
|
||||
if config.LimitUploadRate == 0 || config.LimitUploadBurst == 0 {
|
||||
io.Copy(target, underlying)
|
||||
} else {
|
||||
// Limit upload speed for fallback connection
|
||||
io.Copy(target, &RatelimitedConn{
|
||||
Conn: underlying,
|
||||
Bucket: ratelimit.NewBucketWithRate(config.LimitUploadRate, config.LimitUploadBrust),
|
||||
LimitAfter: config.LimitUploadAfter - config.LimitUploadBrust,
|
||||
Bucket: ratelimit.NewBucketWithRate(config.LimitUploadRate, config.LimitUploadBurst),
|
||||
LimitAfter: config.LimitUploadAfter - config.LimitUploadBurst,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -387,28 +387,28 @@ func Server(ctx context.Context, conn net.Conn, config *Config) (*Conn, error) {
|
||||
if hs.c.conn == conn { // if we processed the Client Hello successfully but the target did not
|
||||
waitGroup.Add(1)
|
||||
go func() {
|
||||
if config.LimitUploadRate == 0 || config.LimitUploadBrust == 0 {
|
||||
if config.LimitUploadRate == 0 || config.LimitUploadBurst == 0 {
|
||||
io.Copy(target, underlying)
|
||||
} else {
|
||||
// Limit upload speed for fallback connection (handshake ok but hello failed)
|
||||
io.Copy(target, &RatelimitedConn{
|
||||
Conn: underlying,
|
||||
Bucket: ratelimit.NewBucketWithRate(config.LimitUploadRate, config.LimitUploadBrust),
|
||||
LimitAfter: config.LimitUploadAfter - config.LimitUploadBrust,
|
||||
Bucket: ratelimit.NewBucketWithRate(config.LimitUploadRate, config.LimitUploadBurst),
|
||||
LimitAfter: config.LimitUploadAfter - config.LimitUploadBurst,
|
||||
})
|
||||
}
|
||||
waitGroup.Done()
|
||||
}()
|
||||
}
|
||||
conn.Write(s2cSaved)
|
||||
if config.LimitDownloadRate == 0 || config.LimitDownloadBrust == 0 {
|
||||
if config.LimitDownloadRate == 0 || config.LimitDownloadBurst == 0 {
|
||||
io.Copy(underlying, target)
|
||||
} else {
|
||||
// Limit download speed for fallback connection
|
||||
io.Copy(underlying, &RatelimitedConn{
|
||||
Conn: target,
|
||||
Bucket: ratelimit.NewBucketWithRate(config.LimitDownloadRate, config.LimitDownloadBrust),
|
||||
LimitAfter: config.LimitDownloadAfter - config.LimitDownloadBrust,
|
||||
Bucket: ratelimit.NewBucketWithRate(config.LimitDownloadRate, config.LimitDownloadBurst),
|
||||
LimitAfter: config.LimitDownloadAfter - config.LimitDownloadBurst,
|
||||
})
|
||||
}
|
||||
// Here is bidirectional direct forwarding:
|
||||
|
Loading…
Reference in New Issue
Block a user