Compare commits
10 Commits
78082cd99f
...
99c9446f1a
Author | SHA1 | Date |
---|---|---|
renovate[bot] | 99c9446f1a | |
renovate[bot] | a5e59aaf2e | |
世界 | 619aad076c | |
世界 | 92b399f5a7 | |
世界 | f297644428 | |
世界 | f11354a96a | |
世界 | 236a26d731 | |
世界 | 78889c9617 | |
世界 | 7452f6f7be | |
世界 | 4716d13850 |
|
@ -30,7 +30,7 @@ jobs:
|
|||
with:
|
||||
go-version: ^1.22
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v5
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
with:
|
||||
version: latest
|
||||
args: --timeout=30m
|
||||
|
|
|
@ -71,6 +71,7 @@ func RouterFromContext(ctx context.Context) Router {
|
|||
|
||||
type HeadlessRule interface {
|
||||
Match(metadata *InboundContext) bool
|
||||
String() string
|
||||
}
|
||||
|
||||
type Rule interface {
|
||||
|
@ -79,7 +80,6 @@ type Rule interface {
|
|||
Type() string
|
||||
UpdateGeosite() error
|
||||
Outbound() string
|
||||
String() string
|
||||
}
|
||||
|
||||
type DNSRule interface {
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/srs"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing-box/route"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/json"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var flagRuleSetMatchFormat string
|
||||
|
||||
var commandRuleSetMatch = &cobra.Command{
|
||||
Use: "match <rule-set path> <domain>",
|
||||
Short: "Check if a domain matches the rule set",
|
||||
Args: cobra.ExactArgs(2),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := ruleSetMatch(args[0], args[1])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
commandRuleSetMatch.Flags().StringVarP(&flagRuleSetMatchFormat, "format", "f", "source", "rule-set format")
|
||||
commandRuleSet.AddCommand(commandRuleSetMatch)
|
||||
}
|
||||
|
||||
func ruleSetMatch(sourcePath string, domain string) error {
|
||||
var (
|
||||
reader io.Reader
|
||||
err error
|
||||
)
|
||||
if sourcePath == "stdin" {
|
||||
reader = os.Stdin
|
||||
} else {
|
||||
reader, err = os.Open(sourcePath)
|
||||
if err != nil {
|
||||
return E.Cause(err, "read rule-set")
|
||||
}
|
||||
}
|
||||
content, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return E.Cause(err, "read rule-set")
|
||||
}
|
||||
var plainRuleSet option.PlainRuleSet
|
||||
switch flagRuleSetMatchFormat {
|
||||
case C.RuleSetFormatSource:
|
||||
var compat option.PlainRuleSetCompat
|
||||
compat, err = json.UnmarshalExtended[option.PlainRuleSetCompat](content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
plainRuleSet = compat.Upgrade()
|
||||
case C.RuleSetFormatBinary:
|
||||
plainRuleSet, err = srs.Read(bytes.NewReader(content), false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return E.New("unknown rule set format: ", flagRuleSetMatchFormat)
|
||||
}
|
||||
for i, ruleOptions := range plainRuleSet.Rules {
|
||||
var currentRule adapter.HeadlessRule
|
||||
currentRule, err = route.NewHeadlessRule(nil, ruleOptions)
|
||||
if err != nil {
|
||||
return E.Cause(err, "parse rule_set.rules.[", i, "]")
|
||||
}
|
||||
if currentRule.Match(&adapter.InboundContext{
|
||||
Domain: domain,
|
||||
}) {
|
||||
println("match rules.[", i, "]: "+currentRule.String())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -32,14 +32,20 @@ func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDi
|
|||
var dialer net.Dialer
|
||||
var listener net.ListenConfig
|
||||
if options.BindInterface != "" {
|
||||
bindFunc := control.BindToInterface(router.InterfaceFinder(), options.BindInterface, -1)
|
||||
var interfaceFinder control.InterfaceFinder
|
||||
if router != nil {
|
||||
interfaceFinder = router.InterfaceFinder()
|
||||
} else {
|
||||
interfaceFinder = control.NewDefaultInterfaceFinder()
|
||||
}
|
||||
bindFunc := control.BindToInterface(interfaceFinder, options.BindInterface, -1)
|
||||
dialer.Control = control.Append(dialer.Control, bindFunc)
|
||||
listener.Control = control.Append(listener.Control, bindFunc)
|
||||
} else if router.AutoDetectInterface() {
|
||||
} else if router != nil && router.AutoDetectInterface() {
|
||||
bindFunc := router.AutoDetectInterfaceFunc()
|
||||
dialer.Control = control.Append(dialer.Control, bindFunc)
|
||||
listener.Control = control.Append(listener.Control, bindFunc)
|
||||
} else if router.DefaultInterface() != "" {
|
||||
} else if router != nil && router.DefaultInterface() != "" {
|
||||
bindFunc := control.BindToInterface(router.InterfaceFinder(), router.DefaultInterface(), -1)
|
||||
dialer.Control = control.Append(dialer.Control, bindFunc)
|
||||
listener.Control = control.Append(listener.Control, bindFunc)
|
||||
|
@ -47,7 +53,7 @@ func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDi
|
|||
if options.RoutingMark != 0 {
|
||||
dialer.Control = control.Append(dialer.Control, control.RoutingMark(options.RoutingMark))
|
||||
listener.Control = control.Append(listener.Control, control.RoutingMark(options.RoutingMark))
|
||||
} else if router.DefaultMark() != 0 {
|
||||
} else if router != nil && router.DefaultMark() != 0 {
|
||||
dialer.Control = control.Append(dialer.Control, control.RoutingMark(router.DefaultMark()))
|
||||
listener.Control = control.Append(listener.Control, control.RoutingMark(router.DefaultMark()))
|
||||
}
|
||||
|
|
|
@ -13,6 +13,9 @@ func New(router adapter.Router, options option.DialerOptions) (N.Dialer, error)
|
|||
if options.IsWireGuardListener {
|
||||
return NewDefault(router, options)
|
||||
}
|
||||
if router == nil {
|
||||
return NewDefault(nil, options)
|
||||
}
|
||||
var (
|
||||
dialer N.Dialer
|
||||
err error
|
||||
|
|
|
@ -2,11 +2,35 @@
|
|||
icon: material/alert-decagram
|
||||
---
|
||||
|
||||
#### 1.9.0-rc.16
|
||||
|
||||
* Mitigating TunnelVision attacks **1**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
See [TunnelVision](/manual/misc/tunnelvision).
|
||||
|
||||
#### 1.9.0-rc.15
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.8.13
|
||||
|
||||
* Fix fake-ip mapping
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.9.0-rc.14
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.9.0-rc.13
|
||||
|
||||
* Update Hysteria protocol
|
||||
* Update quic-go to v0.43.0
|
||||
* Update gVisor to 20240422.0
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.8.12
|
||||
|
||||
* Now we have official APT and DNF repositories **1**
|
||||
|
@ -17,6 +41,10 @@ icon: material/alert-decagram
|
|||
|
||||
Including stable and beta versions, see https://sing-box.sagernet.org/installation/package-manager/
|
||||
|
||||
#### 1.9.0-rc.11
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.8.11
|
||||
|
||||
* Fixes and improvements
|
||||
|
@ -25,6 +53,24 @@ Including stable and beta versions, see https://sing-box.sagernet.org/installati
|
|||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.9.0-beta.17
|
||||
|
||||
* Update `quic-go` to v0.42.0
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.9.0-beta.16
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
_Our Testflight distribution has been temporarily blocked by Apple (possibly due to too many beta versions)
|
||||
and you cannot join the test, install or update the sing-box beta app right now.
|
||||
Please wait patiently for processing._
|
||||
|
||||
#### 1.9.0-beta.14
|
||||
|
||||
* Update gVisor to 20240212.0-65-g71212d503
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.8.9
|
||||
|
||||
* Fixes and improvements
|
||||
|
@ -33,14 +79,125 @@ Including stable and beta versions, see https://sing-box.sagernet.org/installati
|
|||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.9.0-beta.7
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.9.0-beta.6
|
||||
|
||||
* Fix address filter DNS rule items **1**
|
||||
* Fix DNS outbound responding with wrong data
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
Fixed an issue where address filter DNS rule was incorrectly rejected under certain circumstances.
|
||||
If you have enabled `store_rdrc` to save results, consider clearing the cache file.
|
||||
|
||||
#### 1.8.7
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.9.0-alpha.15
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.9.0-alpha.14
|
||||
|
||||
* Improve DNS truncate behavior
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.9.0-alpha.13
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.8.6
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.9.0-alpha.12
|
||||
|
||||
* Handle Windows power events
|
||||
* Always disable cache for fake-ip DNS transport if `dns.independent_cache` disabled
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.9.0-alpha.11
|
||||
|
||||
* Fix missing `rule_set_ipcidr_match_source` item in DNS rules **1**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
See [DNS Rule](/configuration/dns/rule/).
|
||||
|
||||
#### 1.9.0-alpha.10
|
||||
|
||||
* Add `bypass_domain` and `search_domain` platform HTTP proxy options **1**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
See [TUN](/configuration/inbound/tun) inbound.
|
||||
|
||||
#### 1.9.0-alpha.8
|
||||
|
||||
* Add rejected DNS response cache support **1**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
The new feature allows you to cache the check results of
|
||||
[Address filter DNS rule items](/configuration/dns/rule/#address-filter-fields) until expiration.
|
||||
|
||||
#### 1.9.0-alpha.7
|
||||
|
||||
* Update gVisor to 20240206.0
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.9.0-alpha.6
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.9.0-alpha.3
|
||||
|
||||
* Update `quic-go` to v0.41.0
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.9.0-alpha.2
|
||||
|
||||
* Add support for `client-subnet` DNS options **1**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
See [DNS](/configuration/dns), [DNS Server](/configuration/dns/server) and [DNS Rules](/configuration/dns/rule).
|
||||
|
||||
Since this feature makes the scenario mentioned in `alpha.1` no longer leak DNS requests,
|
||||
the [Client example](/manual/proxy/client#traffic-bypass-usage-for-chinese-users) has been updated.
|
||||
|
||||
#### 1.9.0-alpha.1
|
||||
|
||||
* `domain_suffix` behavior update **1**
|
||||
* `process_path` format update on Windows **2**
|
||||
* Add address filter DNS rule items **3**
|
||||
|
||||
**1**:
|
||||
|
||||
See [Migration](/migration/#domain_suffix-behavior-update).
|
||||
|
||||
**2**:
|
||||
|
||||
See [Migration](/migration/#process_path-format-update-on-windows).
|
||||
|
||||
**3**:
|
||||
|
||||
The new DNS feature allows you to more precisely bypass Chinese websites via **DNS leaks**. Do not use plain local DNS
|
||||
if using this method.
|
||||
|
||||
See [Address Filter Fields](/configuration/dns/rule#address-filter-fields).
|
||||
|
||||
[Client example](/manual/proxy/client#traffic-bypass-usage-for-chinese-users) updated.
|
||||
|
||||
#### 1.8.5
|
||||
|
||||
* Fixes and improvements
|
||||
|
@ -390,7 +547,7 @@ see [TCP Brutal](/configuration/shared/tcp-brutal/) for details.
|
|||
|
||||
**5**:
|
||||
|
||||
Only supported in graphical clients on Android and iOS.
|
||||
Only supported in graphical clients on Android and Apple platforms.
|
||||
|
||||
#### 1.7.0-rc.3
|
||||
|
||||
|
@ -427,7 +584,7 @@ Only supported in graphical clients on Android and iOS.
|
|||
|
||||
**1**:
|
||||
|
||||
Only supported in graphical clients on Android and iOS.
|
||||
Only supported in graphical clients on Android and Apple platforms.
|
||||
|
||||
#### 1.7.0-beta.3
|
||||
|
||||
|
|
|
@ -287,7 +287,7 @@ Match Clash mode.
|
|||
|
||||
!!! quote ""
|
||||
|
||||
Only supported in graphical clients on Android and iOS.
|
||||
Only supported in graphical clients on Android and Apple platforms.
|
||||
|
||||
Match WiFi SSID.
|
||||
|
||||
|
@ -295,7 +295,7 @@ Match WiFi SSID.
|
|||
|
||||
!!! quote ""
|
||||
|
||||
Only supported in graphical clients on Android and iOS.
|
||||
Only supported in graphical clients on Android and Apple platforms.
|
||||
|
||||
Match WiFi BSSID.
|
||||
|
||||
|
|
|
@ -285,7 +285,7 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
|
|||
|
||||
!!! quote ""
|
||||
|
||||
仅在 Android 与 iOS 的图形客户端中支持。
|
||||
仅在 Android 与 Apple 平台图形客户端中支持。
|
||||
|
||||
匹配 WiFi SSID。
|
||||
|
||||
|
@ -293,7 +293,7 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
|
|||
|
||||
!!! quote ""
|
||||
|
||||
仅在 Android 与 iOS 的图形客户端中支持。
|
||||
仅在 Android 与 Apple 平台图形客户端中支持。
|
||||
|
||||
匹配 WiFi BSSID。
|
||||
|
||||
|
|
|
@ -42,6 +42,6 @@ No authentication required if empty.
|
|||
|
||||
!!! warning ""
|
||||
|
||||
To work on Android and iOS without privileges, use tun.platform.http_proxy instead.
|
||||
To work on Android and Apple platforms without privileges, use tun.platform.http_proxy instead.
|
||||
|
||||
Automatically set system proxy configuration when start and clean up when stop.
|
||||
|
|
|
@ -39,6 +39,6 @@ No authentication required if empty.
|
|||
|
||||
!!! warning ""
|
||||
|
||||
To work on Android and iOS without privileges, use tun.platform.http_proxy instead.
|
||||
To work on Android and Apple platforms without privileges, use tun.platform.http_proxy instead.
|
||||
|
||||
Automatically set system proxy configuration when start and clean up when stop.
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
---
|
||||
icon: material/new-box
|
||||
---
|
||||
|
||||
!!! quote "Changes in sing-box 1.9.0"
|
||||
|
||||
:material-plus: [platform.http_proxy.bypass_domain](#platformhttp_proxybypass_domain)
|
||||
:material-plus: [platform.http_proxy.match_domain](#platformhttp_proxymatch_domain)
|
||||
|
||||
!!! quote "Changes in sing-box 1.8.0"
|
||||
|
||||
:material-plus: [gso](#gso)
|
||||
|
@ -69,7 +78,9 @@
|
|||
"http_proxy": {
|
||||
"enabled": false,
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8080
|
||||
"server_port": 8080,
|
||||
"bypass_domain": [],
|
||||
"match_domain": []
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -256,6 +267,38 @@ Platform-specific settings, provided by client applications.
|
|||
|
||||
System HTTP proxy settings.
|
||||
|
||||
#### platform.http_proxy.enabled
|
||||
|
||||
Enable system HTTP proxy.
|
||||
|
||||
#### platform.http_proxy.server
|
||||
|
||||
==Required==
|
||||
|
||||
HTTP proxy server address.
|
||||
|
||||
#### platform.http_proxy.server_port
|
||||
|
||||
==Required==
|
||||
|
||||
HTTP proxy server port.
|
||||
|
||||
#### platform.http_proxy.bypass_domain
|
||||
|
||||
!!! note ""
|
||||
|
||||
On Apple platforms, `bypass_domain` items matches hostname **suffixes**.
|
||||
|
||||
Hostnames that bypass the HTTP proxy.
|
||||
|
||||
#### platform.http_proxy.match_domain
|
||||
|
||||
!!! quote ""
|
||||
|
||||
Only supported in graphical clients on Apple platforms.
|
||||
|
||||
Hostnames that use the HTTP proxy.
|
||||
|
||||
### Listen Fields
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen/) for details.
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
---
|
||||
icon: material/new-box
|
||||
---
|
||||
|
||||
!!! quote "sing-box 1.9.0 中的更改"
|
||||
|
||||
:material-plus: [platform.http_proxy.bypass_domain](#platformhttp_proxybypass_domain)
|
||||
:material-plus: [platform.http_proxy.match_domain](#platformhttp_proxymatch_domain)
|
||||
|
||||
!!! quote "sing-box 1.8.0 中的更改"
|
||||
|
||||
:material-plus: [gso](#gso)
|
||||
|
@ -69,7 +78,9 @@
|
|||
"http_proxy": {
|
||||
"enabled": false,
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8080
|
||||
"server_port": 8080,
|
||||
"bypass_domain": [],
|
||||
"match_domain": []
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -253,6 +264,38 @@ TCP/IP 栈。
|
|||
|
||||
系统 HTTP 代理设置。
|
||||
|
||||
##### platform.http_proxy.enabled
|
||||
|
||||
启用系统 HTTP 代理。
|
||||
|
||||
##### platform.http_proxy.server
|
||||
|
||||
==必填==
|
||||
|
||||
系统 HTTP 代理服务器地址。
|
||||
|
||||
##### platform.http_proxy.server_port
|
||||
|
||||
==必填==
|
||||
|
||||
系统 HTTP 代理服务器端口。
|
||||
|
||||
##### platform.http_proxy.bypass_domain
|
||||
|
||||
!!! note ""
|
||||
|
||||
在 Apple 平台,`bypass_domain` 项匹配主机名 **后缀**.
|
||||
|
||||
绕过代理的主机名列表。
|
||||
|
||||
##### platform.http_proxy.match_domain
|
||||
|
||||
!!! quote ""
|
||||
|
||||
仅在 Apple 平台图形客户端中支持。
|
||||
|
||||
代理的主机名列表。
|
||||
|
||||
### 监听字段
|
||||
|
||||
参阅 [监听字段](/zh/configuration/shared/listen/)。
|
||||
|
|
|
@ -281,7 +281,7 @@ Match Clash mode.
|
|||
|
||||
!!! quote ""
|
||||
|
||||
Only supported in graphical clients on Android and iOS.
|
||||
Only supported in graphical clients on Android and Apple platforms.
|
||||
|
||||
Match WiFi SSID.
|
||||
|
||||
|
@ -289,7 +289,7 @@ Match WiFi SSID.
|
|||
|
||||
!!! quote ""
|
||||
|
||||
Only supported in graphical clients on Android and iOS.
|
||||
Only supported in graphical clients on Android and Apple platforms.
|
||||
|
||||
Match WiFi BSSID.
|
||||
|
||||
|
|
|
@ -279,7 +279,7 @@
|
|||
|
||||
!!! quote ""
|
||||
|
||||
仅在 Android 与 iOS 的图形客户端中支持。
|
||||
仅在 Android 与 Apple 平台图形客户端中支持。
|
||||
|
||||
匹配 WiFi SSID。
|
||||
|
||||
|
@ -287,7 +287,7 @@
|
|||
|
||||
!!! quote ""
|
||||
|
||||
仅在 Android 与 iOS 的图形客户端中支持。
|
||||
仅在 Android 与 Apple 平台图形客户端中支持。
|
||||
|
||||
匹配 WiFi BSSID。
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ Match android package name.
|
|||
|
||||
!!! quote ""
|
||||
|
||||
Only supported in graphical clients on Android and iOS.
|
||||
Only supported in graphical clients on Android and Apple platforms.
|
||||
|
||||
Match WiFi SSID.
|
||||
|
||||
|
@ -176,7 +176,7 @@ Match WiFi SSID.
|
|||
|
||||
!!! quote ""
|
||||
|
||||
Only supported in graphical clients on Android and iOS.
|
||||
Only supported in graphical clients on Android and Apple platforms.
|
||||
|
||||
Match WiFi BSSID.
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
icon: material/book-lock-open
|
||||
---
|
||||
|
||||
# TunnelVision
|
||||
|
||||
TunnelVision is an attack that uses DHCP option 121 to set higher priority routes
|
||||
so that traffic does not go through the VPN.
|
||||
|
||||
Reference: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-3661
|
||||
|
||||
## Status
|
||||
|
||||
### Android
|
||||
|
||||
Android does not handle DHCP option 121 and is not affected.
|
||||
|
||||
### Apple platforms
|
||||
|
||||
Update [sing-box graphical client](/clients/apple/#download) to `1.9.0-rc.16` or newer,
|
||||
then enable `includeAllNetworks` in `Settings` — `Packet Tunnel` and you will be unaffected.
|
||||
|
||||
Note: when `includeAllNetworks` is enabled, the default TUN stack is changed to `gvisor`,
|
||||
and the `system` and `mixed` stacks are not available.
|
||||
|
||||
### Linux
|
||||
|
||||
Update sing-box to `1.9.0-rc.16` or newer, rules generated by `auto-route` are unaffected.
|
||||
|
||||
### Windows
|
||||
|
||||
No solution yet.
|
||||
|
||||
## Workarounds
|
||||
|
||||
* Don't connect to untrusted networks
|
||||
* Relay untrusted network through another device
|
||||
* Just ignore it
|
|
@ -1,208 +0,0 @@
|
|||
---
|
||||
icon: material/alpha-t-box
|
||||
---
|
||||
|
||||
# TUIC
|
||||
|
||||
A recently popular Chinese-made simple protocol based on QUIC, the selling point is the BBR congestion control algorithm.
|
||||
|
||||
!!! warning
|
||||
|
||||
Even though GFW rarely blocks UDP-based proxies, such protocols actually have far more characteristics than TCP based proxies.
|
||||
|
||||
| Specification | Binary Characteristics | Active Detect Hiddenness |
|
||||
|-----------------------------------------------------------|------------------------|--------------------------|
|
||||
| [GitHub](https://github.com/EAimTY/tuic/blob/dev/SPEC.md) | :material-alert: | :material-check: |
|
||||
|
||||
## Password Generator
|
||||
|
||||
| Generated UUID | Generated Password | Action |
|
||||
|------------------------|----------------------------|-----------------------------------------------------------------|
|
||||
| <code id="uuid"><code> | <code id="password"><code> | <button class="md-button" onclick="generate()">Refresh</button> |
|
||||
|
||||
<script>
|
||||
function generateUUID() {
|
||||
const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
let r = Math.random() * 16 | 0,
|
||||
v = c === 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
document.getElementById("uuid").textContent = uuid;
|
||||
}
|
||||
function generatePassword() {
|
||||
const array = new Uint8Array(16);
|
||||
window.crypto.getRandomValues(array);
|
||||
document.getElementById("password").textContent = btoa(String.fromCharCode.apply(null, array));
|
||||
}
|
||||
function generate() {
|
||||
generateUUID();
|
||||
generatePassword();
|
||||
}
|
||||
generate();
|
||||
</script>
|
||||
|
||||
## :material-server: Server Example
|
||||
|
||||
=== ":material-harddisk: With local certificate"
|
||||
|
||||
```json
|
||||
{
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "tuic",
|
||||
"listen": "::",
|
||||
"listen_port": 8080,
|
||||
"users": [
|
||||
{
|
||||
"name": "sekai",
|
||||
"uuid": "<uuid>",
|
||||
"password": "<password>"
|
||||
}
|
||||
],
|
||||
"congestion_control": "bbr",
|
||||
"tls": {
|
||||
"enabled": true,
|
||||
"server_name": "example.org",
|
||||
"key_path": "/path/to/key.pem",
|
||||
"certificate_path": "/path/to/certificate.pem"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
=== ":material-auto-fix: With ACME"
|
||||
|
||||
```json
|
||||
{
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "tuic",
|
||||
"listen": "::",
|
||||
"listen_port": 8080,
|
||||
"users": [
|
||||
{
|
||||
"name": "sekai",
|
||||
"uuid": "<uuid>",
|
||||
"password": "<password>"
|
||||
}
|
||||
],
|
||||
"congestion_control": "bbr",
|
||||
"tls": {
|
||||
"enabled": true,
|
||||
"server_name": "example.org",
|
||||
"acme": {
|
||||
"domain": "example.org",
|
||||
"email": "admin@example.org"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
=== ":material-cloud: With ACME and Cloudflare API"
|
||||
|
||||
```json
|
||||
{
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "tuic",
|
||||
"listen": "::",
|
||||
"listen_port": 8080,
|
||||
"users": [
|
||||
{
|
||||
"name": "sekai",
|
||||
"uuid": "<uuid>",
|
||||
"password": "<password>"
|
||||
}
|
||||
],
|
||||
"congestion_control": "bbr",
|
||||
"tls": {
|
||||
"enabled": true,
|
||||
"server_name": "example.org",
|
||||
"acme": {
|
||||
"domain": "example.org",
|
||||
"email": "admin@example.org",
|
||||
"dns01_challenge": {
|
||||
"provider": "cloudflare",
|
||||
"api_token": "my_token"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## :material-cellphone-link: Client Example
|
||||
|
||||
=== ":material-web-check: With valid certificate"
|
||||
|
||||
```json
|
||||
{
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "tuic",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8080,
|
||||
"uuid": "<uuid>",
|
||||
"password": "<password>",
|
||||
"congestion_control": "bbr",
|
||||
"tls": {
|
||||
"enabled": true,
|
||||
"server_name": "example.org"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
=== ":material-check: With self-sign certificate"
|
||||
|
||||
!!! info "Tip"
|
||||
|
||||
Use `sing-box merge` command to merge configuration and certificate into one file.
|
||||
|
||||
```json
|
||||
{
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "tuic",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8080,
|
||||
"uuid": "<uuid>",
|
||||
"password": "<password>",
|
||||
"congestion_control": "bbr",
|
||||
"tls": {
|
||||
"enabled": true,
|
||||
"server_name": "example.org",
|
||||
"certificate_path": "/path/to/certificate.pem"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
=== ":material-alert: Ignore certificate verification"
|
||||
|
||||
```json
|
||||
{
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "tuic",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8080,
|
||||
"uuid": "<uuid>",
|
||||
"password": "<password>",
|
||||
"congestion_control": "bbr",
|
||||
"tls": {
|
||||
"enabled": true,
|
||||
"server_name": "example.org",
|
||||
"insecure": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
|
@ -336,10 +336,10 @@ flowchart TB
|
|||
}
|
||||
```
|
||||
|
||||
=== ":material-dns: DNS rules (1.9.0+)"
|
||||
=== ":material-dns: DNS rules (Enhanced, but slower) (1.9.0+)"
|
||||
|
||||
=== ":material-shield-off: With DNS leaks"
|
||||
|
||||
=== ":material-shield-off: With DNS Leaks"
|
||||
|
||||
```json
|
||||
{
|
||||
"dns": {
|
||||
|
@ -376,7 +376,17 @@ flowchart TB
|
|||
"server": "google"
|
||||
},
|
||||
{
|
||||
"rule_set": "geoip-cn",
|
||||
"type": "logical",
|
||||
"mode": "and",
|
||||
"rules": [
|
||||
{
|
||||
"rule_set": "geosite-geolocation-!cn",
|
||||
"invert": true
|
||||
},
|
||||
{
|
||||
"rule_set": "geoip-cn"
|
||||
}
|
||||
],
|
||||
"server": "local"
|
||||
}
|
||||
]
|
||||
|
@ -389,6 +399,12 @@ flowchart TB
|
|||
"format": "binary",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-cn.srs"
|
||||
},
|
||||
{
|
||||
"type": "remote",
|
||||
"tag": "geosite-geolocation-!cn",
|
||||
"format": "binary",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-!cn.srs"
|
||||
},
|
||||
{
|
||||
"type": "remote",
|
||||
"tag": "geoip-cn",
|
||||
|
@ -398,14 +414,18 @@ flowchart TB
|
|||
]
|
||||
},
|
||||
"experimental": {
|
||||
"cache_file": {
|
||||
"enabled": true,
|
||||
"store_rdrc": true
|
||||
},
|
||||
"clash_api": {
|
||||
"default_mode": "Leak"
|
||||
"default_mode": "Enhanced"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
=== ":material-security: Without DNS Leaks (1.9.0-alpha.2+)"
|
||||
=== ":material-security: Without DNS leaks, but slower (1.9.0-alpha.2+)"
|
||||
|
||||
```json
|
||||
{
|
||||
|
@ -439,7 +459,17 @@ flowchart TB
|
|||
"server": "local"
|
||||
},
|
||||
{
|
||||
"rule_set": "geoip-cn",
|
||||
"type": "logical",
|
||||
"mode": "and",
|
||||
"rules": [
|
||||
{
|
||||
"rule_set": "geosite-geolocation-!cn",
|
||||
"invert": true
|
||||
},
|
||||
{
|
||||
"rule_set": "geoip-cn"
|
||||
}
|
||||
],
|
||||
"server": "google",
|
||||
"client_subnet": "114.114.114.114" // Any China client IP address
|
||||
}
|
||||
|
@ -453,6 +483,12 @@ flowchart TB
|
|||
"format": "binary",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-cn.srs"
|
||||
},
|
||||
{
|
||||
"type": "remote",
|
||||
"tag": "geosite-geolocation-!cn",
|
||||
"format": "binary",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-!cn.srs"
|
||||
},
|
||||
{
|
||||
"type": "remote",
|
||||
"tag": "geoip-cn",
|
||||
|
@ -460,6 +496,15 @@ flowchart TB
|
|||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs"
|
||||
}
|
||||
]
|
||||
},
|
||||
"experimental": {
|
||||
"cache_file": {
|
||||
"enabled": true,
|
||||
"store_rdrc": true
|
||||
},
|
||||
"clash_api": {
|
||||
"default_mode": "Enhanced"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
@ -82,6 +82,10 @@ func (s *platformInterfaceStub) UnderNetworkExtension() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (s *platformInterfaceStub) IncludeAllNetworks() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *platformInterfaceStub) ClearDNSCache() {
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ type PlatformInterface interface {
|
|||
UsePlatformInterfaceGetter() bool
|
||||
GetInterfaces() (NetworkInterfaceIterator, error)
|
||||
UnderNetworkExtension() bool
|
||||
IncludeAllNetworks() bool
|
||||
ReadWIFIState() *WIFIState
|
||||
ClearDNSCache()
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ type Interface interface {
|
|||
UsePlatformInterfaceGetter() bool
|
||||
Interfaces() ([]control.Interface, error)
|
||||
UnderNetworkExtension() bool
|
||||
IncludeAllNetworks() bool
|
||||
ClearDNSCache()
|
||||
ReadWIFIState() adapter.WIFIState
|
||||
process.Searcher
|
||||
|
|
|
@ -213,6 +213,10 @@ func (w *platformInterfaceWrapper) UnderNetworkExtension() bool {
|
|||
return w.iif.UnderNetworkExtension()
|
||||
}
|
||||
|
||||
func (w *platformInterfaceWrapper) IncludeAllNetworks() bool {
|
||||
return w.iif.IncludeAllNetworks()
|
||||
}
|
||||
|
||||
func (w *platformInterfaceWrapper) ClearDNSCache() {
|
||||
w.iif.ClearDNSCache()
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ type TunOptions interface {
|
|||
IsHTTPProxyEnabled() bool
|
||||
GetHTTPProxyServer() string
|
||||
GetHTTPProxyServerPort() int32
|
||||
GetHTTPProxyBypassDomain() StringIterator
|
||||
GetHTTPProxyMatchDomain() StringIterator
|
||||
}
|
||||
|
||||
type RoutePrefix struct {
|
||||
|
@ -156,3 +158,11 @@ func (o *tunOptions) GetHTTPProxyServer() string {
|
|||
func (o *tunOptions) GetHTTPProxyServerPort() int32 {
|
||||
return int32(o.TunPlatformOptions.HTTPProxy.ServerPort)
|
||||
}
|
||||
|
||||
func (o *tunOptions) GetHTTPProxyBypassDomain() StringIterator {
|
||||
return newIterator(o.TunPlatformOptions.HTTPProxy.BypassDomain)
|
||||
}
|
||||
|
||||
func (o *tunOptions) GetHTTPProxyMatchDomain() StringIterator {
|
||||
return newIterator(o.TunPlatformOptions.HTTPProxy.MatchDomain)
|
||||
}
|
||||
|
|
4
go.mod
4
go.mod
|
@ -23,7 +23,7 @@ require (
|
|||
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
|
||||
github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1
|
||||
github.com/sagernet/gomobile v0.1.3
|
||||
github.com/sagernet/gvisor v0.0.0-20231209105102-8d27a30e436e
|
||||
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f
|
||||
github.com/sagernet/quic-go v0.43.0-beta.3
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
|
||||
github.com/sagernet/sing v0.4.0-beta.18
|
||||
|
@ -33,7 +33,7 @@ require (
|
|||
github.com/sagernet/sing-shadowsocks v0.2.6
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.0
|
||||
github.com/sagernet/sing-shadowtls v0.1.4
|
||||
github.com/sagernet/sing-tun v0.2.7
|
||||
github.com/sagernet/sing-tun v0.3.0-beta.1
|
||||
github.com/sagernet/sing-vmess v0.1.8
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7
|
||||
github.com/sagernet/tfo-go v0.0.0-20231209031829-7b5343ac1dc6
|
||||
|
|
8
go.sum
8
go.sum
|
@ -97,8 +97,8 @@ github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1 h1:YbmpqPQ
|
|||
github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1/go.mod h1:J2yAxTFPDjrDPhuAi9aWFz2L3ox9it4qAluBBbN0H5k=
|
||||
github.com/sagernet/gomobile v0.1.3 h1:ohjIb1Ou2+1558PnZour3od69suSuvkdSVOlO1tC4B8=
|
||||
github.com/sagernet/gomobile v0.1.3/go.mod h1:Pqq2+ZVvs10U7xK+UwJgwYWUykewi8H6vlslAO73n9E=
|
||||
github.com/sagernet/gvisor v0.0.0-20231209105102-8d27a30e436e h1:DOkjByVeAR56dkszjnMZke4wr7yM/1xHaJF3G9olkEE=
|
||||
github.com/sagernet/gvisor v0.0.0-20231209105102-8d27a30e436e/go.mod h1:fLxq/gtp0qzkaEwywlRRiGmjOK5ES/xUzyIKIFP2Asw=
|
||||
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f h1:NkhuupzH5ch7b/Y/6ZHJWrnNLoiNnSJaow6DPb8VW2I=
|
||||
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f/go.mod h1:KXmw+ouSJNOsuRpg4wgwwCQuunrGz4yoAqQjsLjc6N0=
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||
github.com/sagernet/quic-go v0.43.0-beta.3 h1:qclJbbpgZe76EH62Bdu3LfDSC2zmuxj7zXCpdQBbe7c=
|
||||
|
@ -120,8 +120,8 @@ github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wK
|
|||
github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
|
||||
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
|
||||
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
|
||||
github.com/sagernet/sing-tun v0.2.7 h1:6QtJkeSj6BTTQPGxbbiuV8eh7GdV46w2G0N8CmISwdc=
|
||||
github.com/sagernet/sing-tun v0.2.7/go.mod h1:MKAAHUzVfj7d9zos4lsz6wjXu86/mJyd/gejiAnWj/w=
|
||||
github.com/sagernet/sing-tun v0.3.0-beta.1 h1:OdVK+/hoD6qWHy/SUwpwqFR+IScI3FIQvBDLR05xWSk=
|
||||
github.com/sagernet/sing-tun v0.3.0-beta.1/go.mod h1:xPaOkQhngPMILx+/9DMLCFl4vSxUU2tMnCPSlf05HLo=
|
||||
github.com/sagernet/sing-vmess v0.1.8 h1:XVWad1RpTy9b5tPxdm5MCU8cGfrTGdR8qCq6HV2aCNc=
|
||||
github.com/sagernet/sing-vmess v0.1.8/go.mod h1:vhx32UNzTDUkNwOyIjcZQohre1CaytquC5mPplId8uA=
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ=
|
||||
|
|
|
@ -166,6 +166,14 @@ func (t *Tun) Start() error {
|
|||
}
|
||||
t.logger.Trace("creating stack")
|
||||
t.tunIf = tunInterface
|
||||
var (
|
||||
forwarderBindInterface bool
|
||||
includeAllNetworks bool
|
||||
)
|
||||
if t.platformInterface != nil {
|
||||
forwarderBindInterface = true
|
||||
includeAllNetworks = t.platformInterface.IncludeAllNetworks()
|
||||
}
|
||||
t.tunStack, err = tun.NewStack(t.stack, tun.StackOptions{
|
||||
Context: t.ctx,
|
||||
Tun: tunInterface,
|
||||
|
@ -174,8 +182,9 @@ func (t *Tun) Start() error {
|
|||
UDPTimeout: t.udpTimeout,
|
||||
Handler: t,
|
||||
Logger: t.logger,
|
||||
ForwarderBindInterface: t.platformInterface != nil,
|
||||
ForwarderBindInterface: forwarderBindInterface,
|
||||
InterfaceFinder: t.router.InterfaceFinder(),
|
||||
IncludeAllNetworks: includeAllNetworks,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -66,8 +66,9 @@ nav:
|
|||
- Proxy Protocol:
|
||||
- Shadowsocks: manual/proxy-protocol/shadowsocks.md
|
||||
- Trojan: manual/proxy-protocol/trojan.md
|
||||
- TUIC: manual/proxy-protocol/tuic.md
|
||||
- Hysteria 2: manual/proxy-protocol/hysteria2.md
|
||||
- Misc:
|
||||
- TunnelVision: manual/misc/tunnelvision.md
|
||||
- Configuration:
|
||||
- configuration/index.md
|
||||
- Log:
|
||||
|
|
|
@ -7,4 +7,6 @@ type TunPlatformOptions struct {
|
|||
type HTTPProxyOptions struct {
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
ServerOptions
|
||||
BypassDomain Listable[string] `json:"bypass_domain,omitempty"`
|
||||
MatchDomain Listable[string] `json:"match_domain,omitempty"`
|
||||
}
|
||||
|
|
|
@ -129,14 +129,18 @@ func NewDefaultHeadlessRule(router adapter.Router, options option.DefaultHeadles
|
|||
rule.allItems = append(rule.allItems, item)
|
||||
}
|
||||
if len(options.WIFISSID) > 0 {
|
||||
item := NewWIFISSIDItem(router, options.WIFISSID)
|
||||
rule.items = append(rule.items, item)
|
||||
rule.allItems = append(rule.allItems, item)
|
||||
if router != nil {
|
||||
item := NewWIFISSIDItem(router, options.WIFISSID)
|
||||
rule.items = append(rule.items, item)
|
||||
rule.allItems = append(rule.allItems, item)
|
||||
}
|
||||
}
|
||||
if len(options.WIFIBSSID) > 0 {
|
||||
item := NewWIFIBSSIDItem(router, options.WIFIBSSID)
|
||||
rule.items = append(rule.items, item)
|
||||
rule.allItems = append(rule.allItems, item)
|
||||
if router != nil {
|
||||
item := NewWIFIBSSIDItem(router, options.WIFIBSSID)
|
||||
rule.items = append(rule.items, item)
|
||||
rule.allItems = append(rule.allItems, item)
|
||||
}
|
||||
}
|
||||
return rule, nil
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ type StackDevice struct {
|
|||
stack *stack.Stack
|
||||
mtu uint32
|
||||
events chan wgTun.Event
|
||||
outbound chan stack.PacketBufferPtr
|
||||
outbound chan *stack.PacketBuffer
|
||||
packetOutbound chan *buf.Buffer
|
||||
done chan struct{}
|
||||
dispatcher stack.NetworkDispatcher
|
||||
|
@ -52,7 +52,7 @@ func NewStackDevice(localAddresses []netip.Prefix, mtu uint32) (*StackDevice, er
|
|||
stack: ipStack,
|
||||
mtu: mtu,
|
||||
events: make(chan wgTun.Event, 1),
|
||||
outbound: make(chan stack.PacketBufferPtr, 256),
|
||||
outbound: make(chan *stack.PacketBuffer, 256),
|
||||
packetOutbound: make(chan *buf.Buffer, 256),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
|
@ -283,10 +283,10 @@ func (ep *wireEndpoint) ARPHardwareType() header.ARPHardwareType {
|
|||
return header.ARPHardwareNone
|
||||
}
|
||||
|
||||
func (ep *wireEndpoint) AddHeader(buffer stack.PacketBufferPtr) {
|
||||
func (ep *wireEndpoint) AddHeader(buffer *stack.PacketBuffer) {
|
||||
}
|
||||
|
||||
func (ep *wireEndpoint) ParseHeader(ptr stack.PacketBufferPtr) bool {
|
||||
func (ep *wireEndpoint) ParseHeader(ptr *stack.PacketBuffer) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue