mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-06-12 05:14:14 +08:00
Compare commits
3 Commits
de63430234
...
6778350f65
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6778350f65 | ||
![]() |
914711152f | ||
![]() |
8bbc9af405 |
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@ -30,7 +30,7 @@ jobs:
|
||||
with:
|
||||
go-version: ^1.24.3
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
uses: golangci/golangci-lint-action@v8
|
||||
with:
|
||||
version: latest
|
||||
args: --timeout=30m
|
||||
|
@ -74,6 +74,7 @@ type InboundContext struct {
|
||||
UDPTimeout time.Duration
|
||||
TLSFragment bool
|
||||
TLSFragmentFallbackDelay time.Duration
|
||||
TLSRecordFragment bool
|
||||
|
||||
NetworkStrategy *C.NetworkStrategy
|
||||
NetworkType []C.InterfaceType
|
||||
|
@ -1,7 +1,9 @@
|
||||
package tf
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"math/rand"
|
||||
"net"
|
||||
"strings"
|
||||
@ -17,17 +19,19 @@ type Conn struct {
|
||||
tcpConn *net.TCPConn
|
||||
ctx context.Context
|
||||
firstPacketWritten bool
|
||||
splitRecord bool
|
||||
fallbackDelay time.Duration
|
||||
}
|
||||
|
||||
func NewConn(conn net.Conn, ctx context.Context, fallbackDelay time.Duration) (*Conn, error) {
|
||||
func NewConn(conn net.Conn, ctx context.Context, splitRecord bool, fallbackDelay time.Duration) *Conn {
|
||||
tcpConn, _ := N.UnwrapReader(conn).(*net.TCPConn)
|
||||
return &Conn{
|
||||
Conn: conn,
|
||||
tcpConn: tcpConn,
|
||||
ctx: ctx,
|
||||
splitRecord: splitRecord,
|
||||
fallbackDelay: fallbackDelay,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Conn) Write(b []byte) (n int, err error) {
|
||||
@ -37,10 +41,12 @@ func (c *Conn) Write(b []byte) (n int, err error) {
|
||||
}()
|
||||
serverName := indexTLSServerName(b)
|
||||
if serverName != nil {
|
||||
if c.tcpConn != nil {
|
||||
err = c.tcpConn.SetNoDelay(true)
|
||||
if err != nil {
|
||||
return
|
||||
if !c.splitRecord {
|
||||
if c.tcpConn != nil {
|
||||
err = c.tcpConn.SetNoDelay(true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
splits := strings.Split(serverName.ServerName, ".")
|
||||
@ -61,16 +67,25 @@ func (c *Conn) Write(b []byte) (n int, err error) {
|
||||
currentIndex++
|
||||
}
|
||||
}
|
||||
var buffer bytes.Buffer
|
||||
for i := 0; i <= len(splitIndexes); i++ {
|
||||
var payload []byte
|
||||
if i == 0 {
|
||||
payload = b[:splitIndexes[i]]
|
||||
if c.splitRecord {
|
||||
payload = payload[recordLayerHeaderLen:]
|
||||
}
|
||||
} else if i == len(splitIndexes) {
|
||||
payload = b[splitIndexes[i-1]:]
|
||||
} else {
|
||||
payload = b[splitIndexes[i-1]:splitIndexes[i]]
|
||||
}
|
||||
if c.tcpConn != nil && i != len(splitIndexes) {
|
||||
if c.splitRecord {
|
||||
payloadLen := uint16(len(payload))
|
||||
buffer.Write(b[:3])
|
||||
binary.Write(&buffer, binary.BigEndian, payloadLen)
|
||||
buffer.Write(payload)
|
||||
} else if c.tcpConn != nil && i != len(splitIndexes) {
|
||||
err = writeAndWaitAck(c.ctx, c.tcpConn, payload, c.fallbackDelay)
|
||||
if err != nil {
|
||||
return
|
||||
@ -82,11 +97,18 @@ func (c *Conn) Write(b []byte) (n int, err error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if c.tcpConn != nil {
|
||||
err = c.tcpConn.SetNoDelay(false)
|
||||
if c.splitRecord {
|
||||
_, err = c.tcpConn.Write(buffer.Bytes())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if c.tcpConn != nil {
|
||||
err = c.tcpConn.SetNoDelay(false)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return len(b), nil
|
||||
}
|
||||
|
32
common/tlsfragment/conn_test.go
Normal file
32
common/tlsfragment/conn_test.go
Normal file
@ -0,0 +1,32 @@
|
||||
package tf_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
tf "github.com/sagernet/sing-box/common/tlsfragment"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestTLSFragment(t *testing.T) {
|
||||
t.Parallel()
|
||||
tcpConn, err := net.Dial("tcp", "1.1.1.1:443")
|
||||
require.NoError(t, err)
|
||||
tlsConn := tls.Client(tf.NewConn(tcpConn, context.Background(), false, 0), &tls.Config{
|
||||
ServerName: "www.cloudflare.com",
|
||||
})
|
||||
require.NoError(t, tlsConn.Handshake())
|
||||
}
|
||||
|
||||
func TestTLSRecordFragment(t *testing.T) {
|
||||
t.Parallel()
|
||||
tcpConn, err := net.Dial("tcp", "1.1.1.1:443")
|
||||
require.NoError(t, err)
|
||||
tlsConn := tls.Client(tf.NewConn(tcpConn, context.Background(), true, 0), &tls.Config{
|
||||
ServerName: "www.cloudflare.com",
|
||||
})
|
||||
require.NoError(t, tlsConn.Handshake())
|
||||
}
|
@ -2,6 +2,26 @@
|
||||
icon: material/alert-decagram
|
||||
---
|
||||
|
||||
#### 1.12.0-beta.13
|
||||
|
||||
* Add TLS record fragment route options **1**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
See [Route Action](/configuration/route/rule_action/#tls_record_fragment).
|
||||
|
||||
#### 1.12.0-beta.10
|
||||
|
||||
* Add control options for listeners **1**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
You can now set `bind_interface`, `routing_mark` and `reuse_addr` in Listen Fields.
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen/).
|
||||
|
||||
### 1.11.10
|
||||
|
||||
* Undeprecate the `block` outbound **1**
|
||||
@ -15,6 +35,11 @@ we decided to temporarily undeprecate the `block` outbound until a replacement i
|
||||
_We are temporarily unable to update sing-box apps on the App Store because the reviewer mistakenly found that we
|
||||
violated the rules (TestFlight users are not affected)._
|
||||
|
||||
#### 1.12.0-beta.9
|
||||
|
||||
* Update quic-go to v0.51.0
|
||||
* Fixes and improvements
|
||||
|
||||
### 1.11.9
|
||||
|
||||
* Fixes and improvements
|
||||
@ -22,6 +47,10 @@ violated the rules (TestFlight users are not affected)._
|
||||
_We are temporarily unable to update sing-box apps on the App Store because the reviewer mistakenly found that we
|
||||
violated the rules (TestFlight users are not affected)._
|
||||
|
||||
#### 1.12.0-beta.5
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
### 1.11.8
|
||||
|
||||
* Improve `auto_redirect` **1**
|
||||
@ -35,6 +64,10 @@ see [Tun](/configuration/inbound/tun/#auto_redirect).
|
||||
_We are temporarily unable to update sing-box apps on the App Store because the reviewer mistakenly found that we
|
||||
violated the rules (TestFlight users are not affected)._
|
||||
|
||||
#### 1.12.0-beta.3
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
### 1.11.7
|
||||
|
||||
* Fixes and improvements
|
||||
@ -42,6 +75,15 @@ violated the rules (TestFlight users are not affected)._
|
||||
_We are temporarily unable to update sing-box apps on the App Store because the reviewer mistakenly found that we
|
||||
violated the rules (TestFlight users are not affected)._
|
||||
|
||||
#### 1.12.0-beta.1
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
Now `auto_redirect` fixes compatibility issues between tun and Docker bridge networks,
|
||||
see [Tun](/configuration/inbound/tun/#auto_redirect).
|
||||
|
||||
### 1.11.6
|
||||
|
||||
* Fixes and improvements
|
||||
@ -49,6 +91,40 @@ violated the rules (TestFlight users are not affected)._
|
||||
_We are temporarily unable to update sing-box apps on the App Store because the reviewer mistakenly found that we
|
||||
violated the rules (TestFlight users are not affected)._
|
||||
|
||||
#### 1.12.0-alpha.19
|
||||
|
||||
* Update gVisor to 20250319.0
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.12.0-alpha.18
|
||||
|
||||
* Add wildcard SNI support for ShadowTLS inbound **1**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
See [ShadowTLS](/configuration/inbound/shadowtls/#wildcard_sni).
|
||||
|
||||
#### 1.12.0-alpha.17
|
||||
|
||||
* Add NTP sniffer **1**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
See [Protocol Sniff](/configuration/route/sniff/).
|
||||
|
||||
#### 1.12.0-alpha.16
|
||||
|
||||
* Update `domain_resolver` behavior **1**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
`route.default_domain_resolver` or `outbound.domain_resolver` is now optional when only one DNS server is configured.
|
||||
|
||||
See [Dial Fields](/configuration/shared/dial/#domain_resolver).
|
||||
|
||||
### 1.11.5
|
||||
|
||||
* Fixes and improvements
|
||||
@ -56,10 +132,71 @@ violated the rules (TestFlight users are not affected)._
|
||||
_We are temporarily unable to update sing-box apps on the App Store because the reviewer mistakenly found that we
|
||||
violated the rules (TestFlight users are not affected)._
|
||||
|
||||
#### 1.12.0-alpha.13
|
||||
|
||||
* Move `predefined` DNS server to DNS rule action **1**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
See [DNS Rule Action](/configuration/dns/rule_action/#predefined).
|
||||
|
||||
### 1.11.4
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.12.0-alpha.11
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.12.0-alpha.10
|
||||
|
||||
* Add AnyTLS protocol **1**
|
||||
* Improve `resolve` route action **2**
|
||||
* Migrate to stdlib ECH implementation **3**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
The new AnyTLS protocol claims to mitigate TLS proxy traffic characteristics and comes with a new multiplexing scheme.
|
||||
|
||||
See [AnyTLS Inbound](/configuration/inbound/anytls/) and [AnyTLS Outbound](/configuration/outbound/anytls/).
|
||||
|
||||
**2**:
|
||||
|
||||
`resolve` route action now accepts `disable_cache` and other options like in DNS route actions, see [Route Action](/configuration/route/rule_action).
|
||||
|
||||
**3**:
|
||||
|
||||
See [TLS](/configuration/shared/tls).
|
||||
|
||||
The build tag `with_ech` is no longer needed and has been removed.
|
||||
|
||||
#### 1.12.0-alpha.7
|
||||
|
||||
* Add Tailscale DNS server **1**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
See [Tailscale](/configuration/dns/server/tailscale/).
|
||||
|
||||
#### 1.12.0-alpha.6
|
||||
|
||||
* Add Tailscale endpoint **1**
|
||||
* Drop support for go1.22 **2**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
See [Tailscale](/configuration/endpoint/tailscale/).
|
||||
|
||||
**2**:
|
||||
|
||||
Due to maintenance difficulties, sing-box 1.12.0 requires at least Go 1.23 to compile.
|
||||
|
||||
For Windows 7 users, legacy binaries now continue to compile with Go 1.23 and patches from [MetaCubeX/go](https://github.com/MetaCubeX/go).
|
||||
|
||||
### 1.11.3
|
||||
|
||||
* Fixes and improvements
|
||||
@ -67,10 +204,69 @@ violated the rules (TestFlight users are not affected)._
|
||||
_This version overwrites 1.11.2, as incorrect binaries were released due to a bug in the continuous integration
|
||||
process._
|
||||
|
||||
#### 1.12.0-alpha.5
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
### 1.11.1
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.12.0-alpha.2
|
||||
|
||||
* Update quic-go to v0.49.0
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.12.0-alpha.1
|
||||
|
||||
* Refactor DNS servers **1**
|
||||
* Add domain resolver options**2**
|
||||
* Add TLS fragment route options **3**
|
||||
* Add certificate options **4**
|
||||
|
||||
**1**:
|
||||
|
||||
DNS servers are refactored for better performance and scalability.
|
||||
|
||||
See [DNS server](/configuration/dns/server/).
|
||||
|
||||
For migration, see [Migrate to new DNS server formats](/migration/#migrate-to-new-dns-servers).
|
||||
|
||||
Compatibility for old formats will be removed in sing-box 1.14.0.
|
||||
|
||||
**2**:
|
||||
|
||||
Legacy `outbound` DNS rules are deprecated
|
||||
and can be replaced by the new `domain_resolver` option.
|
||||
|
||||
See [Dial Fields](/configuration/shared/dial/#domain_resolver) and
|
||||
[Route](/configuration/route/#default_domain_resolver).
|
||||
|
||||
For migration,
|
||||
see [Migrate outbound DNS rule items to domain resolver](/migration/#migrate-outbound-dns-rule-items-to-domain-resolver).
|
||||
|
||||
**3**:
|
||||
|
||||
The new TLS fragment route options allow you to fragment TLS handshakes to bypass firewalls.
|
||||
|
||||
This feature is intended to circumvent simple firewalls based on **plaintext packet matching**, and should not be used
|
||||
to circumvent real censorship.
|
||||
|
||||
Since it is not designed for performance, it should not be applied to all connections, but only to server names that are
|
||||
known to be blocked.
|
||||
|
||||
See [Route Action](/configuration/route/rule_action/#tls_fragment).
|
||||
|
||||
**4**:
|
||||
|
||||
New certificate options allow you to manage the default list of trusted X509 CA certificates.
|
||||
|
||||
For the system certificate list, fixed Go not reading Android trusted certificates correctly.
|
||||
|
||||
You can also use the Mozilla Included List instead, or add trusted certificates yourself.
|
||||
|
||||
See [Certificate](/configuration/certificate/).
|
||||
|
||||
### 1.11.0
|
||||
|
||||
Important changes since 1.10:
|
||||
|
@ -6,6 +6,7 @@ icon: material/new-box
|
||||
|
||||
:material-plus: [tls_fragment](#tls_fragment)
|
||||
:material-plus: [tls_fragment_fallback_delay](#tls_fragment_fallback_delay)
|
||||
:material-plus: [tls_record_fragment](#tls_record_fragment)
|
||||
:material-plus: [resolve.disable_cache](#disable_cache)
|
||||
:material-plus: [resolve.rewrite_ttl](#rewrite_ttl)
|
||||
:material-plus: [resolve.client_subnet](#client_subnet)
|
||||
@ -91,7 +92,8 @@ Not available when `method` is set to drop.
|
||||
"udp_connect": false,
|
||||
"udp_timeout": "",
|
||||
"tls_fragment": false,
|
||||
"tls_fragment_fallback_delay": ""
|
||||
"tls_fragment_fallback_delay": "",
|
||||
"tls_record_fragment": ""
|
||||
}
|
||||
```
|
||||
|
||||
@ -164,13 +166,19 @@ If no protocol is sniffed, the following ports will be recognized as protocols b
|
||||
|
||||
Fragment TLS handshakes to bypass firewalls.
|
||||
|
||||
This feature is intended to circumvent simple firewalls based on **plaintext packet matching**, and should not be used to circumvent real censorship.
|
||||
This feature is intended to circumvent simple firewalls based on **plaintext packet matching**,
|
||||
and should not be used to circumvent real censorship.
|
||||
|
||||
Since it is not designed for performance, it should not be applied to all connections, but only to server names that are known to be blocked.
|
||||
Due to poor performance, try `tls_record_fragment` first, and only apply to server names known to be blocked.
|
||||
|
||||
On Linux, Apple platforms, (administrator privileges required) Windows, the wait time can be automatically detected, otherwise it will fall back to waiting for a fixed time specified by `tls_fragment_fallback_delay`.
|
||||
On Linux, Apple platforms, (administrator privileges required) Windows,
|
||||
the wait time can be automatically detected, otherwise it will fall back to
|
||||
waiting for a fixed time specified by `tls_fragment_fallback_delay`.
|
||||
|
||||
In addition, if the actual wait time is less than 20ms, it will also fall back to waiting for a fixed time, because the target is considered to be local or behind a transparent proxy.
|
||||
In addition, if the actual wait time is less than 20ms, it will also fall back to waiting for a fixed time,
|
||||
because the target is considered to be local or behind a transparent proxy.
|
||||
|
||||
Conflict with `tls_record_fragment`.
|
||||
|
||||
#### tls_fragment_fallback_delay
|
||||
|
||||
@ -180,6 +188,17 @@ The fallback value used when TLS segmentation cannot automatically determine the
|
||||
|
||||
`500ms` is used by default.
|
||||
|
||||
#### tls_record_fragment
|
||||
|
||||
!!! question "Since sing-box 1.12.0"
|
||||
|
||||
Fragment TLS handshake into multiple TLS records to bypass firewalls.
|
||||
|
||||
This feature is intended to circumvent simple firewalls based on **plaintext packet matching**,
|
||||
and should not be used to circumvent real censorship.
|
||||
|
||||
Conflict with `tls_fragment`.
|
||||
|
||||
### sniff
|
||||
|
||||
```json
|
||||
|
@ -5,7 +5,11 @@ icon: material/new-box
|
||||
!!! quote "sing-box 1.12.0 中的更改"
|
||||
|
||||
:material-plus: [tls_fragment](#tls_fragment)
|
||||
:material-plus: [tls_fragment_fallback_delay](#tls_fragment_fallback_delay)
|
||||
:material-plus: [tls_fragment_fallback_delay](#tls_fragment_fallback_delay)
|
||||
:material-plus: [tls_record_fragment](#tls_record_fragment)
|
||||
:material-plus: [resolve.disable_cache](#disable_cache)
|
||||
:material-plus: [resolve.rewrite_ttl](#rewrite_ttl)
|
||||
:material-plus: [resolve.client_subnet](#client_subnet)
|
||||
|
||||
## 最终动作
|
||||
|
||||
@ -159,12 +163,15 @@ UDP 连接超时时间。
|
||||
|
||||
此功能旨在规避基于**明文数据包匹配**的简单防火墙,不应该用于规避真的审查。
|
||||
|
||||
由于它不是为性能设计的,不应被应用于所有连接,而仅应用于已知被阻止的服务器名称。
|
||||
由于性能不佳,请首先尝试 `tls_record_fragment`,且仅应用于已知被阻止的服务器名称。
|
||||
|
||||
在 Linux、Apple 平台和需要管理员权限的 Windows 系统上,可自动检测等待时间。若无法自动检测,将回退使用 `tls_fragment_fallback_delay` 指定的固定等待时间。
|
||||
在 Linux、Apple 平台和需要管理员权限的 Windows 系统上,可自动检测等待时间。
|
||||
若无法自动检测,将回退使用 `tls_fragment_fallback_delay` 指定的固定等待时间。
|
||||
|
||||
此外,若实际等待时间小于 20 毫秒,同样会回退至固定等待时间模式,因为此时判定目标处于本地或透明代理之后。
|
||||
|
||||
与 `tls_record_fragment` 冲突。
|
||||
|
||||
#### tls_fragment_fallback_delay
|
||||
|
||||
!!! question "自 sing-box 1.12.0 起"
|
||||
@ -173,6 +180,16 @@ UDP 连接超时时间。
|
||||
|
||||
默认使用 `500ms`。
|
||||
|
||||
#### tls_record_fragment
|
||||
|
||||
!!! question "自 sing-box 1.12.0 起"
|
||||
|
||||
通过分段 TLS 握手数据包到多个 TLS 记录来绕过防火墙检测。
|
||||
|
||||
此功能旨在规避基于**明文数据包匹配**的简单防火墙,不应该用于规避真的审查。
|
||||
|
||||
与 `tls_fragment` 冲突。
|
||||
|
||||
### sniff
|
||||
|
||||
```json
|
||||
|
@ -158,6 +158,7 @@ type RawRouteOptionsActionOptions struct {
|
||||
|
||||
TLSFragment bool `json:"tls_fragment,omitempty"`
|
||||
TLSFragmentFallbackDelay badoption.Duration `json:"tls_fragment_fallback_delay,omitempty"`
|
||||
TLSRecordFragment bool `json:"tls_record_fragment,omitempty"`
|
||||
}
|
||||
|
||||
type RouteOptionsActionOptions RawRouteOptionsActionOptions
|
||||
@ -170,6 +171,9 @@ func (r *RouteOptionsActionOptions) UnmarshalJSON(data []byte) error {
|
||||
if *r == (RouteOptionsActionOptions{}) {
|
||||
return E.New("empty route option action")
|
||||
}
|
||||
if r.TLSFragment && r.TLSRecordFragment {
|
||||
return E.New("`tls_fragment` and `tls_record_fragment` are mutually exclusive")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -95,15 +95,9 @@ func (m *ConnectionManager) NewConnection(ctx context.Context, this N.Dialer, co
|
||||
if fallbackDelay == 0 {
|
||||
fallbackDelay = C.TLSFragmentFallbackDelay
|
||||
}
|
||||
var newConn *tf.Conn
|
||||
newConn, err = tf.NewConn(remoteConn, ctx, fallbackDelay)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
remoteConn.Close()
|
||||
m.logger.ErrorContext(ctx, err)
|
||||
return
|
||||
}
|
||||
remoteConn = newConn
|
||||
remoteConn = tf.NewConn(remoteConn, ctx, false, fallbackDelay)
|
||||
} else if metadata.TLSRecordFragment {
|
||||
remoteConn = tf.NewConn(remoteConn, ctx, true, 0)
|
||||
}
|
||||
m.access.Lock()
|
||||
element := m.connections.PushBack(conn)
|
||||
|
@ -40,6 +40,7 @@ func NewRuleAction(ctx context.Context, logger logger.ContextLogger, action opti
|
||||
UDPConnect: action.RouteOptions.UDPConnect,
|
||||
TLSFragment: action.RouteOptions.TLSFragment,
|
||||
TLSFragmentFallbackDelay: time.Duration(action.RouteOptions.TLSFragmentFallbackDelay),
|
||||
TLSRecordFragment: action.RouteOptions.TLSRecordFragment,
|
||||
},
|
||||
}, nil
|
||||
case C.RuleActionTypeRouteOptions:
|
||||
@ -53,6 +54,7 @@ func NewRuleAction(ctx context.Context, logger logger.ContextLogger, action opti
|
||||
UDPTimeout: time.Duration(action.RouteOptionsOptions.UDPTimeout),
|
||||
TLSFragment: action.RouteOptionsOptions.TLSFragment,
|
||||
TLSFragmentFallbackDelay: time.Duration(action.RouteOptionsOptions.TLSFragmentFallbackDelay),
|
||||
TLSRecordFragment: action.RouteOptionsOptions.TLSRecordFragment,
|
||||
}, nil
|
||||
case C.RuleActionTypeDirect:
|
||||
directDialer, err := dialer.New(ctx, option.DialerOptions(action.DirectOptions), false)
|
||||
@ -152,15 +154,7 @@ func (r *RuleActionRoute) Type() string {
|
||||
func (r *RuleActionRoute) String() string {
|
||||
var descriptions []string
|
||||
descriptions = append(descriptions, r.Outbound)
|
||||
if r.UDPDisableDomainUnmapping {
|
||||
descriptions = append(descriptions, "udp-disable-domain-unmapping")
|
||||
}
|
||||
if r.UDPConnect {
|
||||
descriptions = append(descriptions, "udp-connect")
|
||||
}
|
||||
if r.TLSFragment {
|
||||
descriptions = append(descriptions, "tls-fragment")
|
||||
}
|
||||
descriptions = append(descriptions, r.Descriptions()...)
|
||||
return F.ToString("route(", strings.Join(descriptions, ","), ")")
|
||||
}
|
||||
|
||||
@ -176,6 +170,7 @@ type RuleActionRouteOptions struct {
|
||||
UDPTimeout time.Duration
|
||||
TLSFragment bool
|
||||
TLSFragmentFallbackDelay time.Duration
|
||||
TLSRecordFragment bool
|
||||
}
|
||||
|
||||
func (r *RuleActionRouteOptions) Type() string {
|
||||
@ -183,6 +178,10 @@ func (r *RuleActionRouteOptions) Type() string {
|
||||
}
|
||||
|
||||
func (r *RuleActionRouteOptions) String() string {
|
||||
return F.ToString("route-options(", strings.Join(r.Descriptions(), ","), ")")
|
||||
}
|
||||
|
||||
func (r *RuleActionRouteOptions) Descriptions() []string {
|
||||
var descriptions []string
|
||||
if r.OverrideAddress.IsValid() {
|
||||
descriptions = append(descriptions, F.ToString("override-address=", r.OverrideAddress.AddrString()))
|
||||
@ -211,7 +210,16 @@ func (r *RuleActionRouteOptions) String() string {
|
||||
if r.UDPTimeout > 0 {
|
||||
descriptions = append(descriptions, "udp-timeout")
|
||||
}
|
||||
return F.ToString("route-options(", strings.Join(descriptions, ","), ")")
|
||||
if r.TLSFragment {
|
||||
descriptions = append(descriptions, "tls-fragment")
|
||||
}
|
||||
if r.TLSFragmentFallbackDelay > 0 {
|
||||
descriptions = append(descriptions, F.ToString("tls-fragment-fallback-delay=", r.TLSFragmentFallbackDelay.String()))
|
||||
}
|
||||
if r.TLSRecordFragment {
|
||||
descriptions = append(descriptions, "tls-record-fragment")
|
||||
}
|
||||
return descriptions
|
||||
}
|
||||
|
||||
type RuleActionDNSRoute struct {
|
||||
|
Loading…
x
Reference in New Issue
Block a user