mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-10-21 16:54:26 +00:00
Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb6629dc5c | ||
|
|
87237191f3 | ||
|
|
fc2cf83ded | ||
|
|
e61c67cbc2 | ||
|
|
406e089d13 | ||
|
|
256adf4a94 | ||
|
|
a6cf3697c3 | ||
|
|
9a42943070 | ||
|
|
e812102bda | ||
|
|
8ab8734614 | ||
|
|
5b92b7183f | ||
|
|
9aff92b89a |
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Get latest go version
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Go
|
||||
@@ -68,7 +68,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Go
|
||||
@@ -199,7 +199,7 @@ jobs:
|
||||
TAGS: with_clash_api,with_quic
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Get latest go version
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Setup QEMU for Docker Buildx
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Get latest go version
|
||||
|
||||
@@ -16,7 +16,6 @@ builds:
|
||||
- with_quic
|
||||
- with_dhcp
|
||||
- with_wireguard
|
||||
- with_ech
|
||||
- with_utls
|
||||
- with_reality_server
|
||||
- with_clash_api
|
||||
@@ -52,7 +51,6 @@ builds:
|
||||
- with_quic
|
||||
- with_dhcp
|
||||
- with_wireguard
|
||||
- with_ech
|
||||
- with_utls
|
||||
- with_clash_api
|
||||
env:
|
||||
|
||||
@@ -54,7 +54,7 @@ func init() {
|
||||
sharedFlags = append(sharedFlags, "-X github.com/sagernet/sing-box/constant.Version="+currentTag+" -s -w -buildid=")
|
||||
debugFlags = append(debugFlags, "-X github.com/sagernet/sing-box/constant.Version="+currentTag)
|
||||
|
||||
sharedTags = append(sharedTags, "with_gvisor", "with_quic", "with_wireguard", "with_ech", "with_utls", "with_clash_api")
|
||||
sharedTags = append(sharedTags, "with_gvisor", "with_quic", "with_wireguard", "with_utls", "with_clash_api")
|
||||
iosTags = append(iosTags, "with_dhcp", "with_low_memory", "with_conntrack")
|
||||
debugTags = append(debugTags, "debug")
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ func main() {
|
||||
newContent, updated0 := findAndReplace(objectsMap, projectContent, []string{"io.nekohasekai.sfa"}, newVersion.VersionString())
|
||||
newContent, updated1 := findAndReplace(objectsMap, newContent, []string{"io.nekohasekai.sfa.independent", "io.nekohasekai.sfa.system"}, newVersion.String())
|
||||
if updated0 || updated1 {
|
||||
log.Info("updated version to ", newVersion.VersionString(), " (", newVersion.String(), ")")
|
||||
log.Info("updated version to ", newVersion.VersionString())
|
||||
common.Must(os.WriteFile("sing-box.xcodeproj/project.pbxproj.bak", []byte(projectContent), 0o644))
|
||||
common.Must(os.WriteFile("sing-box.xcodeproj/project.pbxproj", []byte(newContent), 0o644))
|
||||
} else {
|
||||
log.Info("version not changed")
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package baderror
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
func Contains(err error, msgList ...string) bool {
|
||||
for _, msg := range msgList {
|
||||
if strings.Contains(err.Error(), msg) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func WrapH2(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
err = E.Unwrap(err)
|
||||
if err == io.ErrUnexpectedEOF {
|
||||
return io.EOF
|
||||
}
|
||||
if Contains(err, "client disconnected", "body closed by handler", "response body closed", "; CANCEL") {
|
||||
return net.ErrClosed
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func WrapGRPC(err error) error {
|
||||
// grpc uses stupid internal error types
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if Contains(err, "EOF") {
|
||||
return io.EOF
|
||||
}
|
||||
if Contains(err, "Canceled") {
|
||||
return context.Canceled
|
||||
}
|
||||
if Contains(err,
|
||||
"the client connection is closing",
|
||||
"server closed the stream without sending trailers") {
|
||||
return net.ErrClosed
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func WrapQUIC(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if Contains(err, "canceled by local with error code 0") {
|
||||
return net.ErrClosed
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -1,73 +1,43 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
F "github.com/sagernet/sing/common/format"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
"github.com/sagernet/sing/common/shell"
|
||||
)
|
||||
|
||||
type AndroidSystemProxy struct {
|
||||
useRish bool
|
||||
rishPath string
|
||||
serverAddr M.Socksaddr
|
||||
supportSOCKS bool
|
||||
isEnabled bool
|
||||
}
|
||||
var (
|
||||
useRish bool
|
||||
rishPath string
|
||||
)
|
||||
|
||||
func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, supportSOCKS bool) (*AndroidSystemProxy, error) {
|
||||
func init() {
|
||||
userId := os.Getuid()
|
||||
var (
|
||||
useRish bool
|
||||
rishPath string
|
||||
)
|
||||
if userId == 0 || userId == 1000 || userId == 2000 {
|
||||
useRish = false
|
||||
} else {
|
||||
rishPath, useRish = C.FindPath("rish")
|
||||
if !useRish {
|
||||
return nil, E.Cause(os.ErrPermission, "root or system (adb) permission is required for set system proxy")
|
||||
}
|
||||
}
|
||||
return &AndroidSystemProxy{
|
||||
useRish: useRish,
|
||||
rishPath: rishPath,
|
||||
serverAddr: serverAddr,
|
||||
supportSOCKS: supportSOCKS,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *AndroidSystemProxy) IsEnabled() bool {
|
||||
return p.isEnabled
|
||||
}
|
||||
|
||||
func (p *AndroidSystemProxy) Enable() error {
|
||||
err := p.runAndroidShell("settings", "put", "global", "http_proxy", p.serverAddr.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.isEnabled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *AndroidSystemProxy) Disable() error {
|
||||
err := p.runAndroidShell("settings", "put", "global", "http_proxy", ":0")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.isEnabled = false
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *AndroidSystemProxy) runAndroidShell(name string, args ...string) error {
|
||||
if !p.useRish {
|
||||
func runAndroidShell(name string, args ...string) error {
|
||||
if !useRish {
|
||||
return shell.Exec(name, args...).Attach().Run()
|
||||
} else {
|
||||
return shell.Exec("sh", p.rishPath, "-c", F.ToString(name, " ", strings.Join(args, " "))).Attach().Run()
|
||||
return shell.Exec("sh", rishPath, "-c", F.ToString(name, " ", strings.Join(args, " "))).Attach().Run()
|
||||
}
|
||||
}
|
||||
|
||||
func SetSystemProxy(router adapter.Router, port uint16, isMixed bool) (func() error, error) {
|
||||
err := runAndroidShell("settings", "put", "global", "http_proxy", F.ToString("127.0.0.1:", port))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return func() error {
|
||||
return runAndroidShell("settings", "put", "global", "http_proxy", ":0")
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/netip"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-tun"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
F "github.com/sagernet/sing/common/format"
|
||||
"github.com/sagernet/sing/common/shell"
|
||||
"github.com/sagernet/sing/common/x/list"
|
||||
)
|
||||
|
||||
type DarwinSystemProxy struct {
|
||||
type systemProxy struct {
|
||||
monitor tun.DefaultInterfaceMonitor
|
||||
interfaceName string
|
||||
element *list.Element[tun.DefaultInterfaceUpdateCallback]
|
||||
serverAddr M.Socksaddr
|
||||
supportSOCKS bool
|
||||
isEnabled bool
|
||||
port uint16
|
||||
isMixed bool
|
||||
}
|
||||
|
||||
func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, supportSOCKS bool) (*DarwinSystemProxy, error) {
|
||||
interfaceMonitor := adapter.RouterFromContext(ctx).InterfaceMonitor()
|
||||
if interfaceMonitor == nil {
|
||||
return nil, E.New("missing interface monitor")
|
||||
func (p *systemProxy) update(event int) {
|
||||
newInterfaceName := p.monitor.DefaultInterfaceName(netip.IPv4Unspecified())
|
||||
if p.interfaceName == newInterfaceName {
|
||||
return
|
||||
}
|
||||
proxy := &DarwinSystemProxy{
|
||||
monitor: interfaceMonitor,
|
||||
serverAddr: serverAddr,
|
||||
supportSOCKS: supportSOCKS,
|
||||
if p.interfaceName != "" {
|
||||
_ = p.unset()
|
||||
}
|
||||
proxy.element = interfaceMonitor.RegisterCallback(proxy.update)
|
||||
return proxy, nil
|
||||
p.interfaceName = newInterfaceName
|
||||
interfaceDisplayName, err := getInterfaceDisplayName(p.interfaceName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if p.isMixed {
|
||||
err = shell.Exec("networksetup", "-setsocksfirewallproxy", interfaceDisplayName, "127.0.0.1", F.ToString(p.port)).Attach().Run()
|
||||
}
|
||||
if err == nil {
|
||||
err = shell.Exec("networksetup", "-setwebproxy", interfaceDisplayName, "127.0.0.1", F.ToString(p.port)).Attach().Run()
|
||||
}
|
||||
if err == nil {
|
||||
_ = shell.Exec("networksetup", "-setsecurewebproxy", interfaceDisplayName, "127.0.0.1", F.ToString(p.port)).Attach().Run()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (p *DarwinSystemProxy) IsEnabled() bool {
|
||||
return p.isEnabled
|
||||
}
|
||||
|
||||
func (p *DarwinSystemProxy) Enable() error {
|
||||
return p.update0()
|
||||
}
|
||||
|
||||
func (p *DarwinSystemProxy) Disable() error {
|
||||
func (p *systemProxy) unset() error {
|
||||
interfaceDisplayName, err := getInterfaceDisplayName(p.interfaceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if p.supportSOCKS {
|
||||
if p.isMixed {
|
||||
err = shell.Exec("networksetup", "-setsocksfirewallproxystate", interfaceDisplayName, "off").Attach().Run()
|
||||
}
|
||||
if err == nil {
|
||||
@@ -59,53 +59,9 @@ func (p *DarwinSystemProxy) Disable() error {
|
||||
if err == nil {
|
||||
err = shell.Exec("networksetup", "-setsecurewebproxystate", interfaceDisplayName, "off").Attach().Run()
|
||||
}
|
||||
if err == nil {
|
||||
p.isEnabled = false
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *DarwinSystemProxy) update(event int) {
|
||||
if event&tun.EventInterfaceUpdate == 0 {
|
||||
return
|
||||
}
|
||||
if !p.isEnabled {
|
||||
return
|
||||
}
|
||||
_ = p.update0()
|
||||
}
|
||||
|
||||
func (p *DarwinSystemProxy) update0() error {
|
||||
newInterfaceName := p.monitor.DefaultInterfaceName(netip.IPv4Unspecified())
|
||||
if p.interfaceName == newInterfaceName {
|
||||
return nil
|
||||
}
|
||||
if p.interfaceName != "" {
|
||||
_ = p.Disable()
|
||||
}
|
||||
p.interfaceName = newInterfaceName
|
||||
interfaceDisplayName, err := getInterfaceDisplayName(p.interfaceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if p.supportSOCKS {
|
||||
err = shell.Exec("networksetup", "-setsocksfirewallproxy", interfaceDisplayName, p.serverAddr.AddrString(), strconv.Itoa(int(p.serverAddr.Port))).Attach().Run()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = shell.Exec("networksetup", "-setwebproxy", interfaceDisplayName, p.serverAddr.AddrString(), strconv.Itoa(int(p.serverAddr.Port))).Attach().Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = shell.Exec("networksetup", "-setsecurewebproxy", interfaceDisplayName, p.serverAddr.AddrString(), strconv.Itoa(int(p.serverAddr.Port))).Attach().Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.isEnabled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func getInterfaceDisplayName(name string) (string, error) {
|
||||
content, err := shell.Exec("networksetup", "-listallhardwareports").ReadOutput()
|
||||
if err != nil {
|
||||
@@ -121,3 +77,21 @@ func getInterfaceDisplayName(name string) (string, error) {
|
||||
}
|
||||
return "", E.New(name, " not found in networksetup -listallhardwareports")
|
||||
}
|
||||
|
||||
func SetSystemProxy(router adapter.Router, port uint16, isMixed bool) (func() error, error) {
|
||||
interfaceMonitor := router.InterfaceMonitor()
|
||||
if interfaceMonitor == nil {
|
||||
return nil, E.New("missing interface monitor")
|
||||
}
|
||||
proxy := &systemProxy{
|
||||
monitor: interfaceMonitor,
|
||||
port: port,
|
||||
isMixed: isMixed,
|
||||
}
|
||||
proxy.update(tun.EventInterfaceUpdate)
|
||||
proxy.element = interfaceMonitor.RegisterCallback(proxy.update)
|
||||
return func() error {
|
||||
interfaceMonitor.UnregisterCallback(proxy.element)
|
||||
return proxy.unset()
|
||||
}, nil
|
||||
}
|
||||
|
||||
+78
-109
@@ -3,137 +3,106 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing/common"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
F "github.com/sagernet/sing/common/format"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
"github.com/sagernet/sing/common/shell"
|
||||
)
|
||||
|
||||
type LinuxSystemProxy struct {
|
||||
hasGSettings bool
|
||||
hasKWriteConfig5 bool
|
||||
sudoUser string
|
||||
serverAddr M.Socksaddr
|
||||
supportSOCKS bool
|
||||
isEnabled bool
|
||||
}
|
||||
var (
|
||||
hasGSettings bool
|
||||
isKDE5 bool
|
||||
sudoUser string
|
||||
)
|
||||
|
||||
func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, supportSOCKS bool) (*LinuxSystemProxy, error) {
|
||||
hasGSettings := common.Error(exec.LookPath("gsettings")) == nil
|
||||
hasKWriteConfig5 := common.Error(exec.LookPath("kwriteconfig5")) == nil
|
||||
var sudoUser string
|
||||
func init() {
|
||||
isKDE5 = common.Error(exec.LookPath("kwriteconfig5")) == nil
|
||||
hasGSettings = common.Error(exec.LookPath("gsettings")) == nil
|
||||
if os.Getuid() == 0 {
|
||||
sudoUser = os.Getenv("SUDO_USER")
|
||||
}
|
||||
if !hasGSettings && !hasKWriteConfig5 {
|
||||
return nil, E.New("unsupported desktop environment")
|
||||
}
|
||||
return &LinuxSystemProxy{
|
||||
hasGSettings: hasGSettings,
|
||||
hasKWriteConfig5: hasKWriteConfig5,
|
||||
sudoUser: sudoUser,
|
||||
serverAddr: serverAddr,
|
||||
supportSOCKS: supportSOCKS,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *LinuxSystemProxy) IsEnabled() bool {
|
||||
return p.isEnabled
|
||||
}
|
||||
|
||||
func (p *LinuxSystemProxy) Enable() error {
|
||||
if p.hasGSettings {
|
||||
err := p.runAsUser("gsettings", "set", "org.gnome.system.proxy.http", "enabled", "true")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if p.supportSOCKS {
|
||||
err = p.setGnomeProxy("ftp", "http", "https", "socks")
|
||||
} else {
|
||||
err = p.setGnomeProxy("http", "https")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = p.runAsUser("gsettings", "set", "org.gnome.system.proxy", "use-same-proxy", F.ToString(p.supportSOCKS))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = p.runAsUser("gsettings", "set", "org.gnome.system.proxy", "mode", "manual")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if p.hasKWriteConfig5 {
|
||||
err := p.runAsUser("kwriteconfig5", "--file", "kioslaverc", "--group", "'Proxy Settings'", "--key", "ProxyType", "1")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if p.supportSOCKS {
|
||||
err = p.setKDEProxy("ftp", "http", "https", "socks")
|
||||
} else {
|
||||
err = p.setKDEProxy("http", "https")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = p.runAsUser("kwriteconfig5", "--file", "kioslaverc", "--group", "'Proxy Settings'", "--key", "Authmode", "0")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = p.runAsUser("dbus-send", "--type=signal", "/KIO/Scheduler", "org.kde.KIO.Scheduler.reparseSlaveConfiguration", "string:''")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
p.isEnabled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *LinuxSystemProxy) Disable() error {
|
||||
if p.hasGSettings {
|
||||
err := p.runAsUser("gsettings", "set", "org.gnome.system.proxy", "mode", "none")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if p.hasKWriteConfig5 {
|
||||
err := p.runAsUser("kwriteconfig5", "--file", "kioslaverc", "--group", "'Proxy Settings'", "--key", "ProxyType", "0")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = p.runAsUser("dbus-send", "--type=signal", "/KIO/Scheduler", "org.kde.KIO.Scheduler.reparseSlaveConfiguration", "string:''")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
p.isEnabled = false
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *LinuxSystemProxy) runAsUser(name string, args ...string) error {
|
||||
func runAsUser(name string, args ...string) error {
|
||||
if os.Getuid() != 0 {
|
||||
return shell.Exec(name, args...).Attach().Run()
|
||||
} else if p.sudoUser != "" {
|
||||
return shell.Exec("su", "-", p.sudoUser, "-c", F.ToString(name, " ", strings.Join(args, " "))).Attach().Run()
|
||||
} else if sudoUser != "" {
|
||||
return shell.Exec("su", "-", sudoUser, "-c", F.ToString(name, " ", strings.Join(args, " "))).Attach().Run()
|
||||
} else {
|
||||
return E.New("set system proxy: unable to set as root")
|
||||
}
|
||||
}
|
||||
|
||||
func (p *LinuxSystemProxy) setGnomeProxy(proxyTypes ...string) error {
|
||||
func SetSystemProxy(router adapter.Router, port uint16, isMixed bool) (func() error, error) {
|
||||
if hasGSettings {
|
||||
err := runAsUser("gsettings", "set", "org.gnome.system.proxy.http", "enabled", "true")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if isMixed {
|
||||
err = setGnomeProxy(port, "ftp", "http", "https", "socks")
|
||||
} else {
|
||||
err = setGnomeProxy(port, "http", "https")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = runAsUser("gsettings", "set", "org.gnome.system.proxy", "use-same-proxy", F.ToString(isMixed))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = runAsUser("gsettings", "set", "org.gnome.system.proxy", "mode", "manual")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return func() error {
|
||||
return runAsUser("gsettings", "set", "org.gnome.system.proxy", "mode", "none")
|
||||
}, nil
|
||||
}
|
||||
if isKDE5 {
|
||||
err := runAsUser("kwriteconfig5", "--file", "kioslaverc", "--group", "'Proxy Settings'", "--key", "ProxyType", "1")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if isMixed {
|
||||
err = setKDEProxy(port, "ftp", "http", "https", "socks")
|
||||
} else {
|
||||
err = setKDEProxy(port, "http", "https")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = runAsUser("kwriteconfig5", "--file", "kioslaverc", "--group", "'Proxy Settings'", "--key", "Authmode", "0")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = runAsUser("dbus-send", "--type=signal", "/KIO/Scheduler", "org.kde.KIO.Scheduler.reparseSlaveConfiguration", "string:''")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return func() error {
|
||||
err = runAsUser("kwriteconfig5", "--file", "kioslaverc", "--group", "'Proxy Settings'", "--key", "ProxyType", "0")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return runAsUser("dbus-send", "--type=signal", "/KIO/Scheduler", "org.kde.KIO.Scheduler.reparseSlaveConfiguration", "string:''")
|
||||
}, nil
|
||||
}
|
||||
return nil, E.New("unsupported desktop environment")
|
||||
}
|
||||
|
||||
func setGnomeProxy(port uint16, proxyTypes ...string) error {
|
||||
for _, proxyType := range proxyTypes {
|
||||
err := p.runAsUser("gsettings", "set", "org.gnome.system.proxy."+proxyType, "host", p.serverAddr.AddrString())
|
||||
err := runAsUser("gsettings", "set", "org.gnome.system.proxy."+proxyType, "host", "127.0.0.1")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = p.runAsUser("gsettings", "set", "org.gnome.system.proxy."+proxyType, "port", F.ToString(p.serverAddr.Port))
|
||||
err = runAsUser("gsettings", "set", "org.gnome.system.proxy."+proxyType, "port", F.ToString(port))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -141,20 +110,20 @@ func (p *LinuxSystemProxy) setGnomeProxy(proxyTypes ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *LinuxSystemProxy) setKDEProxy(proxyTypes ...string) error {
|
||||
func setKDEProxy(port uint16, proxyTypes ...string) error {
|
||||
for _, proxyType := range proxyTypes {
|
||||
var proxyUrl string
|
||||
if proxyType == "socks" {
|
||||
proxyUrl = "socks://" + p.serverAddr.String()
|
||||
proxyUrl = "socks://127.0.0.1:" + F.ToString(port)
|
||||
} else {
|
||||
proxyUrl = "http://" + p.serverAddr.String()
|
||||
proxyUrl = "http://127.0.0.1:" + F.ToString(port)
|
||||
}
|
||||
err := p.runAsUser(
|
||||
err := runAsUser(
|
||||
"kwriteconfig5",
|
||||
"--file",
|
||||
"kioslaverc",
|
||||
"--group",
|
||||
"Proxy Settings",
|
||||
"'Proxy Settings'",
|
||||
"--key", proxyType+"Proxy",
|
||||
proxyUrl,
|
||||
)
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
)
|
||||
|
||||
func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, supportSOCKS bool) (SystemProxy, error) {
|
||||
func SetSystemProxy(router adapter.Router, port uint16, isMixed bool) (func() error, error) {
|
||||
return nil, os.ErrInvalid
|
||||
}
|
||||
|
||||
@@ -1,43 +1,17 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
F "github.com/sagernet/sing/common/format"
|
||||
"github.com/sagernet/sing/common/wininet"
|
||||
)
|
||||
|
||||
type WindowsSystemProxy struct {
|
||||
serverAddr M.Socksaddr
|
||||
supportSOCKS bool
|
||||
isEnabled bool
|
||||
}
|
||||
|
||||
func NewSystemProxy(ctx context.Context, serverAddr M.Socksaddr, supportSOCKS bool) (*WindowsSystemProxy, error) {
|
||||
return &WindowsSystemProxy{
|
||||
serverAddr: serverAddr,
|
||||
supportSOCKS: supportSOCKS,
|
||||
func SetSystemProxy(router adapter.Router, port uint16, isMixed bool) (func() error, error) {
|
||||
err := wininet.SetSystemProxy(F.ToString("http://127.0.0.1:", port), "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return func() error {
|
||||
return wininet.ClearSystemProxy()
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *WindowsSystemProxy) IsEnabled() bool {
|
||||
return p.isEnabled
|
||||
}
|
||||
|
||||
func (p *WindowsSystemProxy) Enable() error {
|
||||
err := wininet.SetSystemProxy("http://"+p.serverAddr.String(), "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.isEnabled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *WindowsSystemProxy) Disable() error {
|
||||
err := wininet.ClearSystemProxy()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.isEnabled = false
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package settings
|
||||
|
||||
type SystemProxy interface {
|
||||
IsEnabled() bool
|
||||
Enable() error
|
||||
Disable() error
|
||||
}
|
||||
@@ -178,7 +178,7 @@ func NewECHClient(ctx context.Context, serverAddress string, options option.Outb
|
||||
} else if options.ECH.ConfigPath != "" {
|
||||
content, err := os.ReadFile(options.ECH.ConfigPath)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "read ECH config")
|
||||
return nil, E.Cause(err, "read key")
|
||||
}
|
||||
echConfig = content
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ func (c *echServerConfig) startECHWatcher() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.echWatcher = watcher
|
||||
c.watcher = watcher
|
||||
go c.loopECHUpdate()
|
||||
return nil
|
||||
}
|
||||
@@ -178,7 +178,7 @@ func (c *echServerConfig) loopECHUpdate() {
|
||||
if err != nil {
|
||||
c.logger.Error(E.Cause(err, "reload ECH key"))
|
||||
}
|
||||
case err, ok := <-c.echWatcher.Errors:
|
||||
case err, ok := <-c.watcher.Errors:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
@@ -304,7 +304,7 @@ func NewECHServer(ctx context.Context, logger log.Logger, options option.Inbound
|
||||
} else if options.KeyPath != "" {
|
||||
content, err := os.ReadFile(options.ECH.KeyPath)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "read ECH key")
|
||||
return nil, E.Cause(err, "read key")
|
||||
}
|
||||
echKey = content
|
||||
} else {
|
||||
|
||||
@@ -1,27 +1,3 @@
|
||||
#### 1.5.0-beta.6
|
||||
|
||||
* Fix compatibility issues with official Hysteria2 server and client
|
||||
* Fixes and improvements
|
||||
* Mark [deprecated features](/deprecated)
|
||||
|
||||
#### 1.5.0-beta.5
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.5.0-beta.4
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.5.0-beta.3
|
||||
|
||||
* Fixes and improvements
|
||||
* Updated Hysteria2 documentation **1**
|
||||
|
||||
**1**:
|
||||
|
||||
Added notes indicating compatibility issues with the official
|
||||
Hysteria2 server and client when using `fastOpen=false` or UDP MTU >= 1200.
|
||||
|
||||
#### 1.5.0-beta.2
|
||||
|
||||
* Add hysteria2 protocol support **1**
|
||||
|
||||
@@ -227,13 +227,13 @@ ECH (Encrypted Client Hello) 是一个 TLS 扩展,它允许客户端加密其
|
||||
信息。
|
||||
|
||||
|
||||
ECH 配置和密钥可以通过 `sing-box generate ech-keypair [-pq-signature-schemes-enabled]` 生成。
|
||||
ECH 配置和密钥可以通过 `sing-box generated ech-keypair [-pq-signature-schemes-enabled]` 生成。
|
||||
|
||||
#### pq_signature_schemes_enabled
|
||||
|
||||
启用对后量子对等证书签名方案的支持。
|
||||
|
||||
建议匹配 `sing-box generate ech-keypair` 的参数。
|
||||
建议匹配 `sing-box generated ech-keypair` 的参数。
|
||||
|
||||
#### dynamic_record_sizing_disabled
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
# Deprecated Feature List
|
||||
|
||||
The following features will be marked deprecated in 1.5.0 and removed entirely in 1.6.0.
|
||||
|
||||
#### ShadowsocksR
|
||||
|
||||
ShadowsocksR support has never been enabled by default, since the most commonly used proxy sales panel in the
|
||||
illegal industry stopped using this protocol, it does not make sense to continue to maintain it.
|
||||
|
||||
#### Proxy Protocol
|
||||
|
||||
Proxy Protocol is added by Pull Request, has problems, is only used by the backend of HTTP multiplexers such as nginx,
|
||||
is intrusive, and is meaningless for proxy purposes.
|
||||
@@ -90,7 +90,7 @@ func NewServer(ctx context.Context, router adapter.Router, logFactory log.Observ
|
||||
defaultMode = options.DefaultMode
|
||||
}
|
||||
if !common.Contains(server.modeList, defaultMode) {
|
||||
server.modeList = append([]string{defaultMode}, server.modeList...)
|
||||
server.modeList = append(server.modeList, defaultMode)
|
||||
}
|
||||
server.mode = defaultMode
|
||||
if options.StoreMode || options.StoreSelected || options.StoreFakeIP || options.ExternalController == "" {
|
||||
|
||||
@@ -11,6 +11,4 @@ const (
|
||||
CommandGroupExpand
|
||||
CommandClashMode
|
||||
CommandSetClashMode
|
||||
CommandGetSystemProxyStatus
|
||||
CommandSetSystemProxyEnabled
|
||||
)
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing/common"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
@@ -54,24 +53,9 @@ func (c *CommandClient) directConnect() (net.Conn, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommandClient) directConnectWithRetry() (net.Conn, error) {
|
||||
var (
|
||||
conn net.Conn
|
||||
err error
|
||||
)
|
||||
for i := 0; i < 10; i++ {
|
||||
conn, err = c.directConnect()
|
||||
if err == nil {
|
||||
return conn, nil
|
||||
}
|
||||
time.Sleep(time.Duration(100+i*50) * time.Millisecond)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (c *CommandClient) Connect() error {
|
||||
common.Close(c.conn)
|
||||
conn, err := c.directConnectWithRetry()
|
||||
conn, err := c.directConnect()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -35,8 +35,6 @@ type CommandServer struct {
|
||||
|
||||
type CommandServerHandler interface {
|
||||
ServiceReload() error
|
||||
GetSystemProxyStatus() *SystemProxyStatus
|
||||
SetSystemProxyEnabled(isEnabled bool) error
|
||||
}
|
||||
|
||||
func NewCommandServer(handler CommandServerHandler, maxLines int32) *CommandServer {
|
||||
@@ -161,10 +159,6 @@ func (s *CommandServer) handleConnection(conn net.Conn) error {
|
||||
return s.handleModeConn(conn)
|
||||
case CommandSetClashMode:
|
||||
return s.handleSetClashMode(conn)
|
||||
case CommandGetSystemProxyStatus:
|
||||
return s.handleGetSystemProxyStatus(conn)
|
||||
case CommandSetSystemProxyEnabled:
|
||||
return s.handleSetSystemProxyEnabled(conn)
|
||||
default:
|
||||
return E.New("unknown command: ", command)
|
||||
}
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
package libbox
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"net"
|
||||
)
|
||||
|
||||
type SystemProxyStatus struct {
|
||||
Available bool
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
func (c *CommandClient) GetSystemProxyStatus() (*SystemProxyStatus, error) {
|
||||
conn, err := c.directConnectWithRetry()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Close()
|
||||
err = binary.Write(conn, binary.BigEndian, uint8(CommandGetSystemProxyStatus))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var status SystemProxyStatus
|
||||
err = binary.Read(conn, binary.BigEndian, &status.Available)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if status.Available {
|
||||
err = binary.Read(conn, binary.BigEndian, &status.Enabled)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &status, nil
|
||||
}
|
||||
|
||||
func (s *CommandServer) handleGetSystemProxyStatus(conn net.Conn) error {
|
||||
defer conn.Close()
|
||||
status := s.handler.GetSystemProxyStatus()
|
||||
err := binary.Write(conn, binary.BigEndian, status.Available)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if status.Available {
|
||||
err = binary.Write(conn, binary.BigEndian, status.Enabled)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CommandClient) SetSystemProxyEnabled(isEnabled bool) error {
|
||||
conn, err := c.directConnect()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
err = binary.Write(conn, binary.BigEndian, uint8(CommandSetSystemProxyEnabled))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(conn, binary.BigEndian, isEnabled)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return readError(conn)
|
||||
}
|
||||
|
||||
func (s *CommandServer) handleSetSystemProxyEnabled(conn net.Conn) error {
|
||||
defer conn.Close()
|
||||
var isEnabled bool
|
||||
err := binary.Read(conn, binary.BigEndian, &isEnabled)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = s.handler.SetSystemProxyEnabled(isEnabled)
|
||||
if err != nil {
|
||||
return writeError(conn, err)
|
||||
}
|
||||
return writeError(conn, nil)
|
||||
}
|
||||
@@ -4,7 +4,6 @@ package libbox
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@@ -19,14 +18,12 @@ func RedirectStderr(path string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if runtime.GOOS != "android" {
|
||||
if sUserID > 0 {
|
||||
err = outputFile.Chown(sUserID, sGroupID)
|
||||
if err != nil {
|
||||
outputFile.Close()
|
||||
os.Remove(outputFile.Name())
|
||||
return err
|
||||
}
|
||||
if sUserID > 0 {
|
||||
err = outputFile.Chown(sUserID, sGroupID)
|
||||
if err != nil {
|
||||
outputFile.Close()
|
||||
os.Remove(outputFile.Name())
|
||||
return err
|
||||
}
|
||||
}
|
||||
err = unix.Dup2(int(outputFile.Fd()), int(os.Stderr.Fd()))
|
||||
|
||||
@@ -26,14 +26,14 @@ require (
|
||||
github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2
|
||||
github.com/sagernet/quic-go v0.0.0-20230831052420-45809eee2e86
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
|
||||
github.com/sagernet/sing v0.2.10-0.20230908032232-b0849c43a600
|
||||
github.com/sagernet/sing v0.2.10-0.20230830132630-30bf19f2833c
|
||||
github.com/sagernet/sing-dns v0.1.9-0.20230824120133-4d5cbceb40c1
|
||||
github.com/sagernet/sing-mux v0.1.3-0.20230908032617-759a1886a400
|
||||
github.com/sagernet/sing-shadowsocks v0.2.5-0.20230907005610-126234728ca0
|
||||
github.com/sagernet/sing-shadowsocks2 v0.1.4-0.20230907005906-5d2917b29248
|
||||
github.com/sagernet/sing-mux v0.1.3-0.20230830095209-2a10ebd53ba8
|
||||
github.com/sagernet/sing-shadowsocks v0.2.4
|
||||
github.com/sagernet/sing-shadowsocks2 v0.1.3
|
||||
github.com/sagernet/sing-shadowtls v0.1.4
|
||||
github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641
|
||||
github.com/sagernet/sing-vmess v0.1.8-0.20230907010359-161fb0ac716b
|
||||
github.com/sagernet/sing-vmess v0.1.7
|
||||
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37
|
||||
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6
|
||||
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2
|
||||
|
||||
@@ -112,22 +112,22 @@ github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byL
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
|
||||
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
||||
github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
|
||||
github.com/sagernet/sing v0.2.10-0.20230908032232-b0849c43a600 h1:7kH6R0J1g23vP04v1s8KwfHwFYKOFUo2lOa+Ske6wp8=
|
||||
github.com/sagernet/sing v0.2.10-0.20230908032232-b0849c43a600/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA=
|
||||
github.com/sagernet/sing v0.2.10-0.20230830132630-30bf19f2833c h1:J2ptRncTNy+ZHfcFYSBfTmpvmgNlSEUZz6sDjh1np/Y=
|
||||
github.com/sagernet/sing v0.2.10-0.20230830132630-30bf19f2833c/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA=
|
||||
github.com/sagernet/sing-dns v0.1.9-0.20230824120133-4d5cbceb40c1 h1:5w+jXz8y/8UQAxO74TjftN5okYkpg5mGvVxXunlKdqI=
|
||||
github.com/sagernet/sing-dns v0.1.9-0.20230824120133-4d5cbceb40c1/go.mod h1:Kg98PBJEg/08jsNFtmZWmPomhskn9Ausn50ecNm4M+8=
|
||||
github.com/sagernet/sing-mux v0.1.3-0.20230908032617-759a1886a400 h1:LtpYd5c5AJtUSxjyH4KjUS8HT+2XgilyozjbCq/x3EM=
|
||||
github.com/sagernet/sing-mux v0.1.3-0.20230908032617-759a1886a400/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.5-0.20230907005610-126234728ca0 h1:9wHYWxH+fcs01PM2+DylA8LNNY3ElnZykQo9rysng8U=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.5-0.20230907005610-126234728ca0/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.1.4-0.20230907005906-5d2917b29248 h1:JTFfy/LDmVFEK4KZJEujmC1iO8+aoF4unYhhZZRzRq4=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.1.4-0.20230907005906-5d2917b29248/go.mod h1:DOhJc/cLeqRv0wuePrQso+iUmDxOnWF4eT/oMcRzYFw=
|
||||
github.com/sagernet/sing-mux v0.1.3-0.20230830095209-2a10ebd53ba8 h1:UyUkEUEGqfIGqzOJ7OuJry4slgcT/qb0etDJ+89LTAs=
|
||||
github.com/sagernet/sing-mux v0.1.3-0.20230830095209-2a10ebd53ba8/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.4 h1:s/CqXlvFAZhlIoHWUwPw5CoNnQ9Ibki9pckjuugtVfY=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.4/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.1.3 h1:WXoLvCFi5JTFBRYorf1YePGYIQyJ/zbsBM6Fwbl5kGA=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.1.3/go.mod h1:DOhJc/cLeqRv0wuePrQso+iUmDxOnWF4eT/oMcRzYFw=
|
||||
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.1.12-0.20230821065522-7545dc2d5641 h1:a8lktNrCWZJisB+nPraW+qB73ZofgPtGmlfqNYcO79g=
|
||||
github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641/go.mod h1:+YImslQMLgMQcVgZZ9IK4ue1o/605VSU90amHUcp4hA=
|
||||
github.com/sagernet/sing-vmess v0.1.8-0.20230907010359-161fb0ac716b h1:2ezfJtH5JosiEwJhVa+rimQ6ps/t2+7h+mOzMoiaZnA=
|
||||
github.com/sagernet/sing-vmess v0.1.8-0.20230907010359-161fb0ac716b/go.mod h1:1qkC1L1T2sxnS/NuO6HU72S8TkltV+EXoKGR29m/Yss=
|
||||
github.com/sagernet/sing-vmess v0.1.7 h1:TM8FFLsXmlXH9XT8/oDgc6PC5BOzrg6OzyEe01is2r4=
|
||||
github.com/sagernet/sing-vmess v0.1.7/go.mod h1:1qkC1L1T2sxnS/NuO6HU72S8TkltV+EXoKGR29m/Yss=
|
||||
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
|
||||
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37/go.mod h1:3skNSftZDJWTGVtVaM2jfbce8qHnmH/AGDRe62iNOg0=
|
||||
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 h1:Px+hN4Vzgx+iCGVnWH5A8eR7JhNnIV3rGQmBxA7cw6Q=
|
||||
|
||||
+5
-17
@@ -33,8 +33,8 @@ type myInboundAdapter struct {
|
||||
|
||||
// http mixed
|
||||
|
||||
setSystemProxy bool
|
||||
systemProxy settings.SystemProxy
|
||||
setSystemProxy bool
|
||||
clearSystemProxy func() error
|
||||
|
||||
// internal
|
||||
|
||||
@@ -91,19 +91,7 @@ func (a *myInboundAdapter) Start() error {
|
||||
}
|
||||
}
|
||||
if a.setSystemProxy {
|
||||
listenPort := M.SocksaddrFromNet(a.tcpListener.Addr()).Port
|
||||
var listenAddrString string
|
||||
listenAddr := a.listenOptions.Listen.Build()
|
||||
if listenAddr.IsUnspecified() {
|
||||
listenAddrString = "127.0.0.1"
|
||||
} else {
|
||||
listenAddrString = listenAddr.String()
|
||||
}
|
||||
a.systemProxy, err = settings.NewSystemProxy(a.ctx, M.ParseSocksaddrHostPort(listenAddrString, listenPort), a.protocol == C.TypeMixed)
|
||||
if err != nil {
|
||||
return E.Cause(err, "initialize system proxy")
|
||||
}
|
||||
err = a.systemProxy.Enable()
|
||||
a.clearSystemProxy, err = settings.SetSystemProxy(a.router, M.SocksaddrFromNet(a.tcpListener.Addr()).Port, a.protocol == C.TypeMixed)
|
||||
if err != nil {
|
||||
return E.Cause(err, "set system proxy")
|
||||
}
|
||||
@@ -114,8 +102,8 @@ func (a *myInboundAdapter) Start() error {
|
||||
func (a *myInboundAdapter) Close() error {
|
||||
a.inShutdown.Store(true)
|
||||
var err error
|
||||
if a.systemProxy != nil && a.systemProxy.IsEnabled() {
|
||||
err = a.systemProxy.Disable()
|
||||
if a.clearSystemProxy != nil {
|
||||
err = a.clearSystemProxy()
|
||||
}
|
||||
return E.Errors(err, common.Close(
|
||||
a.tcpListener,
|
||||
|
||||
@@ -35,7 +35,7 @@ func (a *myInboundAdapter) ListenTCP() (net.Listener, error) {
|
||||
a.logger.Info("tcp server started at ", tcpListener.Addr())
|
||||
}
|
||||
if a.listenOptions.ProxyProtocol {
|
||||
a.logger.Warn("Proxy Protocol is deprecated, see https://sing-box.sagernet.org/deprecated")
|
||||
a.logger.Debug("proxy protocol enabled")
|
||||
tcpListener = &proxyproto.Listener{Listener: tcpListener, AcceptNoHeader: a.listenOptions.ProxyProtocolAcceptNoHeader}
|
||||
}
|
||||
a.tcpListener = tcpListener
|
||||
|
||||
+1
-2
@@ -30,10 +30,9 @@ theme:
|
||||
- navigation.sections
|
||||
- header.autohide
|
||||
nav:
|
||||
- Home:
|
||||
- Getting Started:
|
||||
- index.md
|
||||
- Features: features.md
|
||||
- Deprecated: deprecated.md
|
||||
- Support: support.md
|
||||
- Change Log: changelog.md
|
||||
- Installation:
|
||||
|
||||
+3
-77
@@ -65,37 +65,7 @@ func NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata a
|
||||
outConn, err = this.DialContext(ctx, N.NetworkTCP, metadata.Destination)
|
||||
}
|
||||
if err != nil {
|
||||
return N.ReportHandshakeFailure(conn, err)
|
||||
}
|
||||
err = N.ReportHandshakeSuccess(conn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return CopyEarlyConn(ctx, conn, outConn)
|
||||
}
|
||||
|
||||
func NewDirectConnection(ctx context.Context, router adapter.Router, this N.Dialer, conn net.Conn, metadata adapter.InboundContext) error {
|
||||
ctx = adapter.WithContext(ctx, &metadata)
|
||||
var outConn net.Conn
|
||||
var err error
|
||||
if len(metadata.DestinationAddresses) > 0 {
|
||||
outConn, err = N.DialSerial(ctx, this, N.NetworkTCP, metadata.Destination, metadata.DestinationAddresses)
|
||||
} else if metadata.Destination.IsFqdn() {
|
||||
var destinationAddresses []netip.Addr
|
||||
destinationAddresses, err = router.LookupDefault(ctx, metadata.Destination.Fqdn)
|
||||
if err != nil {
|
||||
return N.ReportHandshakeFailure(conn, err)
|
||||
}
|
||||
outConn, err = N.DialSerial(ctx, this, N.NetworkTCP, metadata.Destination, destinationAddresses)
|
||||
} else {
|
||||
outConn, err = this.DialContext(ctx, N.NetworkTCP, metadata.Destination)
|
||||
}
|
||||
if err != nil {
|
||||
return N.ReportHandshakeFailure(conn, err)
|
||||
}
|
||||
err = N.ReportHandshakeSuccess(conn)
|
||||
if err != nil {
|
||||
return err
|
||||
return N.HandshakeFailure(conn, err)
|
||||
}
|
||||
return CopyEarlyConn(ctx, conn, outConn)
|
||||
}
|
||||
@@ -111,51 +81,7 @@ func NewPacketConnection(ctx context.Context, this N.Dialer, conn N.PacketConn,
|
||||
outConn, err = this.ListenPacket(ctx, metadata.Destination)
|
||||
}
|
||||
if err != nil {
|
||||
return N.ReportHandshakeFailure(conn, err)
|
||||
}
|
||||
err = N.ReportHandshakeSuccess(conn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if destinationAddress.IsValid() {
|
||||
if natConn, loaded := common.Cast[bufio.NATPacketConn](conn); loaded {
|
||||
natConn.UpdateDestination(destinationAddress)
|
||||
}
|
||||
}
|
||||
switch metadata.Protocol {
|
||||
case C.ProtocolSTUN:
|
||||
ctx, conn = canceler.NewPacketConn(ctx, conn, C.STUNTimeout)
|
||||
case C.ProtocolQUIC:
|
||||
ctx, conn = canceler.NewPacketConn(ctx, conn, C.QUICTimeout)
|
||||
case C.ProtocolDNS:
|
||||
ctx, conn = canceler.NewPacketConn(ctx, conn, C.DNSTimeout)
|
||||
}
|
||||
return bufio.CopyPacketConn(ctx, conn, bufio.NewPacketConn(outConn))
|
||||
}
|
||||
|
||||
func NewDirectPacketConnection(ctx context.Context, router adapter.Router, this N.Dialer, conn N.PacketConn, metadata adapter.InboundContext) error {
|
||||
ctx = adapter.WithContext(ctx, &metadata)
|
||||
var outConn net.PacketConn
|
||||
var destinationAddress netip.Addr
|
||||
var err error
|
||||
if len(metadata.DestinationAddresses) > 0 {
|
||||
outConn, destinationAddress, err = N.ListenSerial(ctx, this, metadata.Destination, metadata.DestinationAddresses)
|
||||
} else if metadata.Destination.IsFqdn() {
|
||||
var destinationAddresses []netip.Addr
|
||||
destinationAddresses, err = router.LookupDefault(ctx, metadata.Destination.Fqdn)
|
||||
if err != nil {
|
||||
return N.ReportHandshakeFailure(conn, err)
|
||||
}
|
||||
outConn, destinationAddress, err = N.ListenSerial(ctx, this, metadata.Destination, destinationAddresses)
|
||||
} else {
|
||||
outConn, err = this.ListenPacket(ctx, metadata.Destination)
|
||||
}
|
||||
if err != nil {
|
||||
return N.ReportHandshakeFailure(conn, err)
|
||||
}
|
||||
err = N.ReportHandshakeSuccess(conn)
|
||||
if err != nil {
|
||||
return err
|
||||
return N.HandshakeFailure(conn, err)
|
||||
}
|
||||
if destinationAddress.IsValid() {
|
||||
if natConn, loaded := common.Cast[bufio.NATPacketConn](conn); loaded {
|
||||
@@ -203,7 +129,7 @@ func CopyEarlyConn(ctx context.Context, conn net.Conn, serverConn net.Conn) erro
|
||||
}
|
||||
_, err = serverConn.Write(payload.Bytes())
|
||||
if err != nil {
|
||||
return N.ReportHandshakeFailure(conn, err)
|
||||
return N.HandshakeFailure(conn, err)
|
||||
}
|
||||
payload.Release()
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ type ShadowsocksR struct {
|
||||
}
|
||||
|
||||
func NewShadowsocksR(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksROutboundOptions) (*ShadowsocksR, error) {
|
||||
logger.Warn("ShadowsocksR is deprecated, see https://sing-box.sagernet.org/deprecated")
|
||||
outboundDialer, err := dialer.New(router, options.DialerOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
+4
-15
@@ -80,11 +80,11 @@ func (h *Socks) DialContext(ctx context.Context, network string, destination M.S
|
||||
return nil, E.Extend(N.ErrUnknownNetwork, network)
|
||||
}
|
||||
if h.resolve && destination.IsFqdn() {
|
||||
destinationAddresses, err := h.router.LookupDefault(ctx, destination.Fqdn)
|
||||
addrs, err := h.router.LookupDefault(ctx, destination.Fqdn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return N.DialSerial(ctx, h.client, network, destination, destinationAddresses)
|
||||
return N.DialSerial(ctx, h.client, network, destination, addrs)
|
||||
}
|
||||
return h.client.DialContext(ctx, network, destination)
|
||||
}
|
||||
@@ -97,25 +97,14 @@ func (h *Socks) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.
|
||||
h.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination)
|
||||
return h.uotClient.ListenPacket(ctx, destination)
|
||||
}
|
||||
if h.resolve && destination.IsFqdn() {
|
||||
destinationAddresses, err := h.router.LookupDefault(ctx, destination.Fqdn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
packetConn, _, err := N.ListenSerial(ctx, h.client, destination, destinationAddresses)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return packetConn, nil
|
||||
}
|
||||
h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
return h.client.ListenPacket(ctx, destination)
|
||||
}
|
||||
|
||||
func (h *Socks) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
|
||||
return NewDirectConnection(ctx, h.router, h, conn, metadata)
|
||||
return NewConnection(ctx, h, conn, metadata)
|
||||
}
|
||||
|
||||
func (h *Socks) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
|
||||
return NewDirectPacketConnection(ctx, h.router, h, conn, metadata)
|
||||
return NewPacketConnection(ctx, h, conn, metadata)
|
||||
}
|
||||
|
||||
+4
-15
@@ -202,37 +202,26 @@ func (w *WireGuard) DialContext(ctx context.Context, network string, destination
|
||||
w.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
}
|
||||
if destination.IsFqdn() {
|
||||
destinationAddresses, err := w.router.LookupDefault(ctx, destination.Fqdn)
|
||||
addrs, err := w.router.LookupDefault(ctx, destination.Fqdn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return N.DialSerial(ctx, w.tunDevice, network, destination, destinationAddresses)
|
||||
return N.DialSerial(ctx, w.tunDevice, network, destination, addrs)
|
||||
}
|
||||
return w.tunDevice.DialContext(ctx, network, destination)
|
||||
}
|
||||
|
||||
func (w *WireGuard) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||
w.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
if destination.IsFqdn() {
|
||||
destinationAddresses, err := w.router.LookupDefault(ctx, destination.Fqdn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
packetConn, _, err := N.ListenSerial(ctx, w.tunDevice, destination, destinationAddresses)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return packetConn, err
|
||||
}
|
||||
return w.tunDevice.ListenPacket(ctx, destination)
|
||||
}
|
||||
|
||||
func (w *WireGuard) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
|
||||
return NewDirectConnection(ctx, w.router, w, conn, metadata)
|
||||
return NewConnection(ctx, w, conn, metadata)
|
||||
}
|
||||
|
||||
func (w *WireGuard) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
|
||||
return NewDirectPacketConnection(ctx, w.router, w, conn, metadata)
|
||||
return NewPacketConnection(ctx, w, conn, metadata)
|
||||
}
|
||||
|
||||
func (w *WireGuard) Start() error {
|
||||
|
||||
+1
-1
@@ -521,7 +521,7 @@ func (r *Router) Close() error {
|
||||
return E.Cause(err, "close dns transport[", i, "]")
|
||||
})
|
||||
}
|
||||
if r.geoIPReader != nil {
|
||||
if r.geositeReader != nil {
|
||||
r.logger.Trace("closing geoip reader")
|
||||
err = E.Append(err, common.Close(r.geoIPReader), func(err error) error {
|
||||
return E.Cause(err, "close geoip reader")
|
||||
|
||||
+1
-3
@@ -32,8 +32,7 @@ const (
|
||||
ImageTrojan = "trojangfw/trojan:latest"
|
||||
ImageNaive = "pocat/naiveproxy:client"
|
||||
ImageBoringTun = "ghcr.io/ntkme/boringtun:edge"
|
||||
ImageHysteria = "tobyxdd/hysteria:v1.3.5"
|
||||
ImageHysteria2 = "tobyxdd/hysteria:v2"
|
||||
ImageHysteria = "tobyxdd/hysteria:latest"
|
||||
ImageNginx = "nginx:stable"
|
||||
ImageShadowTLS = "ghcr.io/ihciah/shadow-tls:latest"
|
||||
ImageShadowsocksR = "teddysun/shadowsocks-r:latest"
|
||||
@@ -51,7 +50,6 @@ var allImages = []string{
|
||||
ImageNaive,
|
||||
ImageBoringTun,
|
||||
ImageHysteria,
|
||||
ImageHysteria2,
|
||||
ImageNginx,
|
||||
ImageShadowTLS,
|
||||
ImageShadowsocksR,
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
server: 127.0.0.1:10000
|
||||
auth: password
|
||||
socks5:
|
||||
listen: 127.0.0.1:10001
|
||||
tls:
|
||||
sni: example.org
|
||||
ca: /etc/hysteria/ca.pem
|
||||
obfs:
|
||||
type: salamander
|
||||
salamander:
|
||||
password: cry_me_a_r1ver
|
||||
@@ -1,12 +0,0 @@
|
||||
listen: 127.0.0.1:10000
|
||||
auth:
|
||||
type: password
|
||||
password: password
|
||||
tls:
|
||||
sni: example.org
|
||||
cert: /etc/hysteria/cert.pem
|
||||
key: /etc/hysteria/key.pem
|
||||
obfs:
|
||||
type: salamander
|
||||
salamander:
|
||||
password: cry_me_a_r1ver
|
||||
+1
-1
@@ -244,5 +244,5 @@ func TestECHHysteria2(t *testing.T) {
|
||||
},
|
||||
},
|
||||
})
|
||||
testSuitLargeUDP(t, clientPort, testPort)
|
||||
testSuit(t, clientPort, testPort)
|
||||
}
|
||||
|
||||
+5
-5
@@ -10,9 +10,9 @@ require (
|
||||
github.com/docker/docker v24.0.5+incompatible
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/gofrs/uuid/v5 v5.0.0
|
||||
github.com/sagernet/sing v0.2.10-0.20230908032232-b0849c43a600
|
||||
github.com/sagernet/sing-shadowsocks v0.2.5-0.20230907005610-126234728ca0
|
||||
github.com/sagernet/sing-shadowsocks2 v0.1.4-0.20230907005906-5d2917b29248
|
||||
github.com/sagernet/sing v0.2.10-0.20230830132630-30bf19f2833c
|
||||
github.com/sagernet/sing-shadowsocks v0.2.4
|
||||
github.com/sagernet/sing-shadowsocks2 v0.1.3
|
||||
github.com/spyzhov/ajson v0.9.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
go.uber.org/goleak v1.2.1
|
||||
@@ -72,10 +72,10 @@ require (
|
||||
github.com/sagernet/quic-go v0.0.0-20230831052420-45809eee2e86 // indirect
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect
|
||||
github.com/sagernet/sing-dns v0.1.9-0.20230824120133-4d5cbceb40c1 // indirect
|
||||
github.com/sagernet/sing-mux v0.1.3-0.20230908032617-759a1886a400 // indirect
|
||||
github.com/sagernet/sing-mux v0.1.3-0.20230830095209-2a10ebd53ba8 // indirect
|
||||
github.com/sagernet/sing-shadowtls v0.1.4 // indirect
|
||||
github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641 // indirect
|
||||
github.com/sagernet/sing-vmess v0.1.8-0.20230907010359-161fb0ac716b // indirect
|
||||
github.com/sagernet/sing-vmess v0.1.7 // indirect
|
||||
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 // indirect
|
||||
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 // indirect
|
||||
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 // indirect
|
||||
|
||||
+11
-21
@@ -52,8 +52,6 @@ github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
|
||||
github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
@@ -123,29 +121,28 @@ github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2 h1:dnkKrzapqtAwjTS
|
||||
github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2/go.mod h1:1JUiV7nGuf++YFm9eWZ8q2lrwHmhcUGzptMl/vL1+LA=
|
||||
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.0.0-20230825040534-0cd917b2ddda h1:7J/hnOFqCThiCrVpvr0wKO+Dic/XPSulPr5yI8FVJMs=
|
||||
github.com/sagernet/quic-go v0.0.0-20230825040534-0cd917b2ddda/go.mod h1:Iw8Tt3dMqC/61cMHa0nN5i/958oYuuMnQCMOSPx+xcg=
|
||||
github.com/sagernet/quic-go v0.0.0-20230831052420-45809eee2e86 h1:g4TEg9inAtA1FDTXpNrvmx72nN5mTOLQrJce6fVxF9g=
|
||||
github.com/sagernet/quic-go v0.0.0-20230831052420-45809eee2e86/go.mod h1:O4Cj7TmMOvqD6S0XMqJRZfcYzA3m0H0ARbbaJFB0p7A=
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
|
||||
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
||||
github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
|
||||
github.com/sagernet/sing v0.2.10-0.20230908032232-b0849c43a600 h1:7kH6R0J1g23vP04v1s8KwfHwFYKOFUo2lOa+Ske6wp8=
|
||||
github.com/sagernet/sing v0.2.10-0.20230908032232-b0849c43a600/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA=
|
||||
github.com/sagernet/sing v0.2.10-0.20230830132630-30bf19f2833c h1:J2ptRncTNy+ZHfcFYSBfTmpvmgNlSEUZz6sDjh1np/Y=
|
||||
github.com/sagernet/sing v0.2.10-0.20230830132630-30bf19f2833c/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA=
|
||||
github.com/sagernet/sing-dns v0.1.9-0.20230824120133-4d5cbceb40c1 h1:5w+jXz8y/8UQAxO74TjftN5okYkpg5mGvVxXunlKdqI=
|
||||
github.com/sagernet/sing-dns v0.1.9-0.20230824120133-4d5cbceb40c1/go.mod h1:Kg98PBJEg/08jsNFtmZWmPomhskn9Ausn50ecNm4M+8=
|
||||
github.com/sagernet/sing-mux v0.1.3-0.20230908032617-759a1886a400 h1:LtpYd5c5AJtUSxjyH4KjUS8HT+2XgilyozjbCq/x3EM=
|
||||
github.com/sagernet/sing-mux v0.1.3-0.20230908032617-759a1886a400/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.5-0.20230907005610-126234728ca0 h1:9wHYWxH+fcs01PM2+DylA8LNNY3ElnZykQo9rysng8U=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.5-0.20230907005610-126234728ca0/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.1.4-0.20230907005906-5d2917b29248 h1:JTFfy/LDmVFEK4KZJEujmC1iO8+aoF4unYhhZZRzRq4=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.1.4-0.20230907005906-5d2917b29248/go.mod h1:DOhJc/cLeqRv0wuePrQso+iUmDxOnWF4eT/oMcRzYFw=
|
||||
github.com/sagernet/sing-mux v0.1.3-0.20230830095209-2a10ebd53ba8 h1:UyUkEUEGqfIGqzOJ7OuJry4slgcT/qb0etDJ+89LTAs=
|
||||
github.com/sagernet/sing-mux v0.1.3-0.20230830095209-2a10ebd53ba8/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.4 h1:s/CqXlvFAZhlIoHWUwPw5CoNnQ9Ibki9pckjuugtVfY=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.4/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.1.3 h1:WXoLvCFi5JTFBRYorf1YePGYIQyJ/zbsBM6Fwbl5kGA=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.1.3/go.mod h1:DOhJc/cLeqRv0wuePrQso+iUmDxOnWF4eT/oMcRzYFw=
|
||||
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.1.12-0.20230821065522-7545dc2d5641 h1:a8lktNrCWZJisB+nPraW+qB73ZofgPtGmlfqNYcO79g=
|
||||
github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641/go.mod h1:+YImslQMLgMQcVgZZ9IK4ue1o/605VSU90amHUcp4hA=
|
||||
github.com/sagernet/sing-vmess v0.1.8-0.20230907010359-161fb0ac716b h1:2ezfJtH5JosiEwJhVa+rimQ6ps/t2+7h+mOzMoiaZnA=
|
||||
github.com/sagernet/sing-vmess v0.1.8-0.20230907010359-161fb0ac716b/go.mod h1:1qkC1L1T2sxnS/NuO6HU72S8TkltV+EXoKGR29m/Yss=
|
||||
github.com/sagernet/sing-vmess v0.1.7 h1:TM8FFLsXmlXH9XT8/oDgc6PC5BOzrg6OzyEe01is2r4=
|
||||
github.com/sagernet/sing-vmess v0.1.7/go.mod h1:1qkC1L1T2sxnS/NuO6HU72S8TkltV+EXoKGR29m/Yss=
|
||||
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
|
||||
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37/go.mod h1:3skNSftZDJWTGVtVaM2jfbce8qHnmH/AGDRe62iNOg0=
|
||||
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 h1:Px+hN4Vzgx+iCGVnWH5A8eR7JhNnIV3rGQmBxA7cw6Q=
|
||||
@@ -172,7 +169,6 @@ github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695AP
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
|
||||
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
|
||||
github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg=
|
||||
@@ -200,7 +196,6 @@ golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq
|
||||
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
@@ -208,14 +203,12 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -225,9 +218,7 @@ golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -249,7 +240,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E=
|
||||
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -95,92 +95,3 @@ func testHysteria2Self(t *testing.T, salamanderPassword string) {
|
||||
})
|
||||
testSuit(t, clientPort, testPort)
|
||||
}
|
||||
|
||||
func TestHysteria2Inbound(t *testing.T) {
|
||||
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||
startInstance(t, option.Options{
|
||||
Inbounds: []option.Inbound{
|
||||
{
|
||||
Type: C.TypeHysteria2,
|
||||
Hysteria2Options: option.Hysteria2InboundOptions{
|
||||
ListenOptions: option.ListenOptions{
|
||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
||||
ListenPort: serverPort,
|
||||
},
|
||||
Obfs: &option.Hysteria2Obfs{
|
||||
Type: hysteria2.ObfsTypeSalamander,
|
||||
Password: "cry_me_a_r1ver",
|
||||
},
|
||||
Users: []option.Hysteria2User{{
|
||||
Password: "password",
|
||||
}},
|
||||
TLS: &option.InboundTLSOptions{
|
||||
Enabled: true,
|
||||
ServerName: "example.org",
|
||||
CertificatePath: certPem,
|
||||
KeyPath: keyPem,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
startDockerContainer(t, DockerOptions{
|
||||
Image: ImageHysteria2,
|
||||
Ports: []uint16{serverPort, clientPort},
|
||||
Cmd: []string{"client", "-c", "/etc/hysteria/config.yml", "--disable-update-check", "--log-level", "debug"},
|
||||
Bind: map[string]string{
|
||||
"hysteria2-client.yml": "/etc/hysteria/config.yml",
|
||||
caPem: "/etc/hysteria/ca.pem",
|
||||
},
|
||||
})
|
||||
testSuit(t, clientPort, testPort)
|
||||
}
|
||||
|
||||
func TestHysteria2Outbound(t *testing.T) {
|
||||
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
|
||||
startDockerContainer(t, DockerOptions{
|
||||
Image: ImageHysteria2,
|
||||
Ports: []uint16{testPort},
|
||||
Cmd: []string{"server", "-c", "/etc/hysteria/config.yml", "--disable-update-check", "--log-level", "debug"},
|
||||
Bind: map[string]string{
|
||||
"hysteria2-server.yml": "/etc/hysteria/config.yml",
|
||||
certPem: "/etc/hysteria/cert.pem",
|
||||
keyPem: "/etc/hysteria/key.pem",
|
||||
},
|
||||
})
|
||||
startInstance(t, option.Options{
|
||||
Inbounds: []option.Inbound{
|
||||
{
|
||||
Type: C.TypeMixed,
|
||||
MixedOptions: option.HTTPMixedInboundOptions{
|
||||
ListenOptions: option.ListenOptions{
|
||||
Listen: option.NewListenAddress(netip.IPv4Unspecified()),
|
||||
ListenPort: clientPort,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Outbounds: []option.Outbound{
|
||||
{
|
||||
Type: C.TypeHysteria2,
|
||||
Hysteria2Options: option.Hysteria2OutboundOptions{
|
||||
ServerOptions: option.ServerOptions{
|
||||
Server: "127.0.0.1",
|
||||
ServerPort: serverPort,
|
||||
},
|
||||
Obfs: &option.Hysteria2Obfs{
|
||||
Type: hysteria2.ObfsTypeSalamander,
|
||||
Password: "cry_me_a_r1ver",
|
||||
},
|
||||
Password: "password",
|
||||
TLS: &option.OutboundTLSOptions{
|
||||
Enabled: true,
|
||||
ServerName: "example.org",
|
||||
CertificatePath: certPem,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
testSuitSimple1(t, clientPort, testPort)
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/sagernet/quic-go"
|
||||
"github.com/sagernet/sing-box/common/baderror"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/baderror"
|
||||
)
|
||||
|
||||
type PacketConnWrapper struct {
|
||||
|
||||
@@ -17,7 +17,6 @@ import (
|
||||
"github.com/sagernet/sing-box/transport/hysteria2/congestion"
|
||||
"github.com/sagernet/sing-box/transport/hysteria2/internal/protocol"
|
||||
tuicCongestion "github.com/sagernet/sing-box/transport/tuic/congestion"
|
||||
"github.com/sagernet/sing/common/baderror"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
@@ -62,6 +61,7 @@ type Client struct {
|
||||
func NewClient(options ClientOptions) (*Client, error) {
|
||||
quicConfig := &quic.Config{
|
||||
DisablePathMTUDiscovery: !(runtime.GOOS == "windows" || runtime.GOOS == "linux" || runtime.GOOS == "android" || runtime.GOOS == "darwin"),
|
||||
MaxDatagramFrameSize: 1400,
|
||||
EnableDatagrams: true,
|
||||
InitialStreamReceiveWindow: defaultStreamReceiveWindow,
|
||||
MaxStreamReceiveWindow: defaultStreamReceiveWindow,
|
||||
@@ -103,7 +103,7 @@ func (c *Client) offer(ctx context.Context) (*clientQUICConnection, error) {
|
||||
}
|
||||
|
||||
func (c *Client) offerNew(ctx context.Context) (*clientQUICConnection, error) {
|
||||
udpConn, err := c.dialer.DialContext(c.ctx, "udp", c.serverAddr)
|
||||
udpConn, err := c.dialer.DialContext(ctx, "udp", c.serverAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -128,7 +128,7 @@ func (c *Client) offerNew(ctx context.Context) (*clientQUICConnection, error) {
|
||||
Header: make(http.Header),
|
||||
}
|
||||
protocol.AuthRequestToHeader(request.Header, protocol.AuthRequest{Auth: c.password, Rx: c.receiveBPS})
|
||||
response, err := http3Transport.RoundTrip(request.WithContext(ctx))
|
||||
response, err := http3Transport.RoundTrip(request)
|
||||
if err != nil {
|
||||
if quicConn != nil {
|
||||
quicConn.CloseWithError(0, "")
|
||||
@@ -269,20 +269,18 @@ func (c *clientConn) NeedHandshake() bool {
|
||||
|
||||
func (c *clientConn) Read(p []byte) (n int, err error) {
|
||||
if c.responseRead {
|
||||
n, err = c.Stream.Read(p)
|
||||
return n, baderror.WrapQUIC(err)
|
||||
return c.Stream.Read(p)
|
||||
}
|
||||
status, errorMessage, err := protocol.ReadTCPResponse(c.Stream)
|
||||
if err != nil {
|
||||
return 0, baderror.WrapQUIC(err)
|
||||
return
|
||||
}
|
||||
if !status {
|
||||
err = E.New("remote error: ", errorMessage)
|
||||
return
|
||||
}
|
||||
c.responseRead = true
|
||||
n, err = c.Stream.Read(p)
|
||||
return n, baderror.WrapQUIC(err)
|
||||
return c.Stream.Read(p)
|
||||
}
|
||||
|
||||
func (c *clientConn) Write(p []byte) (n int, err error) {
|
||||
@@ -296,8 +294,7 @@ func (c *clientConn) Write(p []byte) (n int, err error) {
|
||||
c.requestWritten = true
|
||||
return len(p), nil
|
||||
}
|
||||
n, err = c.Stream.Write(p)
|
||||
return n, baderror.WrapQUIC(err)
|
||||
return c.Stream.Write(p)
|
||||
}
|
||||
|
||||
func (c *clientConn) LocalAddr() net.Addr {
|
||||
@@ -307,8 +304,3 @@ func (c *clientConn) LocalAddr() net.Addr {
|
||||
func (c *clientConn) RemoteAddr() net.Addr {
|
||||
return M.Socksaddr{}
|
||||
}
|
||||
|
||||
func (c *clientConn) Close() error {
|
||||
c.Stream.CancelRead(0)
|
||||
return c.Stream.Close()
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ func (c *Client) loopMessages(conn *clientQUICConnection) {
|
||||
}
|
||||
|
||||
func (c *Client) handleMessage(conn *clientQUICConnection, data []byte) error {
|
||||
message := allocMessage()
|
||||
message := udpMessagePool.Get().(*udpMessage)
|
||||
err := decodeUDPMessage(message, data)
|
||||
if err != nil {
|
||||
message.release()
|
||||
|
||||
@@ -28,16 +28,11 @@ var udpMessagePool = sync.Pool{
|
||||
},
|
||||
}
|
||||
|
||||
func allocMessage() *udpMessage {
|
||||
message := udpMessagePool.Get().(*udpMessage)
|
||||
message.referenced = true
|
||||
return message
|
||||
}
|
||||
|
||||
func releaseMessages(messages []*udpMessage) {
|
||||
for _, message := range messages {
|
||||
if message != nil {
|
||||
message.release()
|
||||
*message = udpMessage{}
|
||||
udpMessagePool.Put(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,13 +44,9 @@ type udpMessage struct {
|
||||
fragmentTotal uint8
|
||||
destination string
|
||||
data *buf.Buffer
|
||||
referenced bool
|
||||
}
|
||||
|
||||
func (m *udpMessage) release() {
|
||||
if !m.referenced {
|
||||
return
|
||||
}
|
||||
*m = udpMessage{}
|
||||
udpMessagePool.Put(m)
|
||||
}
|
||||
@@ -90,7 +81,7 @@ func fragUDPMessage(message *udpMessage, maxPacketSize int) []*udpMessage {
|
||||
originPacket := message.data.Bytes()
|
||||
udpMTU := maxPacketSize - message.headerSize()
|
||||
for remaining := len(originPacket); remaining > 0; remaining -= udpMTU {
|
||||
fragment := allocMessage()
|
||||
fragment := udpMessagePool.Get().(*udpMessage)
|
||||
*fragment = *message
|
||||
if remaining > udpMTU {
|
||||
fragment.data = buf.As(originPacket[:udpMTU])
|
||||
@@ -216,7 +207,7 @@ func (c *udpPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr)
|
||||
c.packetId.Store(0)
|
||||
packetId = 0
|
||||
}
|
||||
message := allocMessage()
|
||||
message := udpMessagePool.Get().(*udpMessage)
|
||||
*message = udpMessage{
|
||||
sessionID: c.sessionID,
|
||||
packetID: uint16(packetId),
|
||||
@@ -257,7 +248,7 @@ func (c *udpPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
c.packetId.Store(0)
|
||||
packetId = 0
|
||||
}
|
||||
message := allocMessage()
|
||||
message := udpMessagePool.Get().(*udpMessage)
|
||||
*message = udpMessage{
|
||||
sessionID: c.sessionID,
|
||||
packetID: uint16(packetId),
|
||||
@@ -398,10 +389,8 @@ func (d *udpDefragger) feed(m *udpMessage) *udpMessage {
|
||||
if int(item.count) != len(item.messages) {
|
||||
return nil
|
||||
}
|
||||
newMessage := allocMessage()
|
||||
newMessage.sessionID = m.sessionID
|
||||
newMessage.packetID = m.packetID
|
||||
newMessage.destination = item.messages[0].destination
|
||||
newMessage := udpMessagePool.Get().(*udpMessage)
|
||||
*newMessage = *item.messages[0]
|
||||
var finalLength int
|
||||
for _, message := range item.messages {
|
||||
finalLength += message.data.Len()
|
||||
@@ -415,7 +404,6 @@ func (d *udpDefragger) feed(m *udpMessage) *udpMessage {
|
||||
item.messages = nil
|
||||
return newMessage
|
||||
}
|
||||
item.messages = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/sagernet/quic-go"
|
||||
"github.com/sagernet/quic-go/http3"
|
||||
"github.com/sagernet/sing-box/common/baderror"
|
||||
"github.com/sagernet/sing-box/common/qtls"
|
||||
"github.com/sagernet/sing-box/common/tls"
|
||||
"github.com/sagernet/sing-box/transport/hysteria2/congestion"
|
||||
@@ -19,7 +20,6 @@ import (
|
||||
tuicCongestion "github.com/sagernet/sing-box/transport/tuic/congestion"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/auth"
|
||||
"github.com/sagernet/sing/common/baderror"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
@@ -69,6 +69,7 @@ type Server struct {
|
||||
func NewServer(options ServerOptions) (*Server, error) {
|
||||
quicConfig := &quic.Config{
|
||||
DisablePathMTUDiscovery: !(runtime.GOOS == "windows" || runtime.GOOS == "linux" || runtime.GOOS == "android" || runtime.GOOS == "darwin"),
|
||||
MaxDatagramFrameSize: 1400,
|
||||
EnableDatagrams: !options.UDPDisabled,
|
||||
MaxIncomingStreams: 1 << 60,
|
||||
InitialStreamReceiveWindow: defaultStreamReceiveWindow,
|
||||
@@ -240,8 +241,6 @@ func (s *serverSession) handleStream0(frameType http3.FrameType, connection quic
|
||||
}
|
||||
go func() {
|
||||
hErr := s.handleStream(stream)
|
||||
stream.CancelRead(0)
|
||||
stream.Close()
|
||||
if hErr != nil {
|
||||
stream.CancelRead(0)
|
||||
stream.Close()
|
||||
@@ -256,11 +255,14 @@ func (s *serverSession) handleStream(stream quic.Stream) error {
|
||||
if err != nil {
|
||||
return E.New("read TCP request")
|
||||
}
|
||||
var conn net.Conn = &serverConn{
|
||||
Stream: stream,
|
||||
}
|
||||
ctx := s.ctx
|
||||
if s.authUser.Name != "" {
|
||||
ctx = auth.ContextWithUser(s.ctx, s.authUser.Name)
|
||||
}
|
||||
_ = s.handler.NewConnection(ctx, &serverConn{Stream: stream}, M.Metadata{
|
||||
_ = s.handler.NewConnection(ctx, conn, M.Metadata{
|
||||
Source: s.source,
|
||||
Destination: M.ParseSocksaddr(destinationString),
|
||||
})
|
||||
@@ -300,16 +302,6 @@ func (c *serverConn) HandshakeFailure(err error) error {
|
||||
return common.Error(c.Stream.Write(buffer.Bytes()))
|
||||
}
|
||||
|
||||
func (c *serverConn) HandshakeSuccess() error {
|
||||
if c.responseWritten {
|
||||
return nil
|
||||
}
|
||||
c.responseWritten = true
|
||||
buffer := protocol.WriteTCPResponse(true, "", nil)
|
||||
defer buffer.Release()
|
||||
return common.Error(c.Stream.Write(buffer.Bytes()))
|
||||
}
|
||||
|
||||
func (c *serverConn) Read(p []byte) (n int, err error) {
|
||||
n, err = c.Stream.Read(p)
|
||||
return n, baderror.WrapQUIC(err)
|
||||
|
||||
@@ -22,7 +22,7 @@ func (s *serverSession) loopMessages() {
|
||||
}
|
||||
|
||||
func (s *serverSession) handleMessage(data []byte) error {
|
||||
message := allocMessage()
|
||||
message := udpMessagePool.Get().(*udpMessage)
|
||||
err := decodeUDPMessage(message, data)
|
||||
if err != nil {
|
||||
message.release()
|
||||
|
||||
@@ -204,13 +204,10 @@ func ClientHandshake(conn net.Conn, key [KeyLength]byte, destination M.Socksaddr
|
||||
common.Must1(header.Write(key[:]))
|
||||
common.Must1(header.Write(CRLF))
|
||||
common.Must(header.WriteByte(CommandTCP))
|
||||
err := M.SocksaddrSerializer.WriteAddrPort(header, destination)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination))
|
||||
common.Must1(header.Write(CRLF))
|
||||
common.Must1(header.Write(payload))
|
||||
_, err = conn.Write(header.Bytes())
|
||||
_, err := conn.Write(header.Bytes())
|
||||
if err != nil {
|
||||
return E.Cause(err, "write request")
|
||||
}
|
||||
@@ -222,13 +219,10 @@ func ClientHandshakeBuffer(conn net.Conn, key [KeyLength]byte, destination M.Soc
|
||||
common.Must1(header.Write(key[:]))
|
||||
common.Must1(header.Write(CRLF))
|
||||
common.Must(header.WriteByte(CommandTCP))
|
||||
err := M.SocksaddrSerializer.WriteAddrPort(header, destination)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination))
|
||||
common.Must1(header.Write(CRLF))
|
||||
|
||||
_, err = conn.Write(payload.Bytes())
|
||||
_, err := conn.Write(payload.Bytes())
|
||||
if err != nil {
|
||||
return E.Cause(err, "write request")
|
||||
}
|
||||
@@ -250,10 +244,7 @@ func ClientHandshakePacket(conn net.Conn, key [KeyLength]byte, destination M.Soc
|
||||
common.Must1(header.Write(key[:]))
|
||||
common.Must1(header.Write(CRLF))
|
||||
common.Must(header.WriteByte(CommandUDP))
|
||||
err := M.SocksaddrSerializer.WriteAddrPort(header, destination)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination))
|
||||
common.Must1(header.Write(CRLF))
|
||||
common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination))
|
||||
common.Must(binary.Write(header, binary.BigEndian, uint16(payloadLen)))
|
||||
@@ -266,7 +257,7 @@ func ClientHandshakePacket(conn net.Conn, key [KeyLength]byte, destination M.Soc
|
||||
}
|
||||
}
|
||||
|
||||
_, err = conn.Write(payload.Bytes())
|
||||
_, err := conn.Write(payload.Bytes())
|
||||
if err != nil {
|
||||
return E.Cause(err, "write payload")
|
||||
}
|
||||
@@ -298,13 +289,10 @@ func WritePacket(conn net.Conn, buffer *buf.Buffer, destination M.Socksaddr) err
|
||||
defer buffer.Release()
|
||||
bufferLen := buffer.Len()
|
||||
header := buf.With(buffer.ExtendHeader(M.SocksaddrSerializer.AddrPortLen(destination) + 4))
|
||||
err := M.SocksaddrSerializer.WriteAddrPort(header, destination)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination))
|
||||
common.Must(binary.Write(header, binary.BigEndian, uint16(bufferLen)))
|
||||
common.Must1(header.Write(CRLF))
|
||||
_, err = conn.Write(buffer.Bytes())
|
||||
_, err := conn.Write(buffer.Bytes())
|
||||
if err != nil {
|
||||
return E.Cause(err, "write packet")
|
||||
}
|
||||
|
||||
+36
-14
@@ -6,15 +6,16 @@ import (
|
||||
"context"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/quic-go"
|
||||
"github.com/sagernet/sing-box/common/baderror"
|
||||
"github.com/sagernet/sing-box/common/qtls"
|
||||
"github.com/sagernet/sing-box/common/tls"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/baderror"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
@@ -105,7 +106,7 @@ func (c *Client) offer(ctx context.Context) (*clientQUICConnection, error) {
|
||||
}
|
||||
|
||||
func (c *Client) offerNew(ctx context.Context) (*clientQUICConnection, error) {
|
||||
udpConn, err := c.dialer.DialContext(c.ctx, "udp", c.serverAddr)
|
||||
udpConn, err := c.dialer.DialContext(ctx, "udp", c.serverAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -186,8 +187,8 @@ func (c *Client) DialConn(ctx context.Context, destination M.Socksaddr) (net.Con
|
||||
return nil, err
|
||||
}
|
||||
return &clientConn{
|
||||
Stream: stream,
|
||||
parent: conn,
|
||||
stream: stream,
|
||||
destination: destination,
|
||||
}, nil
|
||||
}
|
||||
@@ -255,8 +256,8 @@ func (c *clientQUICConnection) closeWithError(err error) {
|
||||
}
|
||||
|
||||
type clientConn struct {
|
||||
quic.Stream
|
||||
parent *clientQUICConnection
|
||||
stream quic.Stream
|
||||
destination M.Socksaddr
|
||||
requestWritten bool
|
||||
}
|
||||
@@ -266,22 +267,18 @@ func (c *clientConn) NeedHandshake() bool {
|
||||
}
|
||||
|
||||
func (c *clientConn) Read(b []byte) (n int, err error) {
|
||||
n, err = c.Stream.Read(b)
|
||||
n, err = c.stream.Read(b)
|
||||
return n, baderror.WrapQUIC(err)
|
||||
}
|
||||
|
||||
func (c *clientConn) Write(b []byte) (n int, err error) {
|
||||
if !c.requestWritten {
|
||||
request := buf.NewSize(2 + addressSerializer.AddrPortLen(c.destination) + len(b))
|
||||
defer request.Release()
|
||||
request.WriteByte(Version)
|
||||
request.WriteByte(CommandConnect)
|
||||
err = addressSerializer.WriteAddrPort(request, c.destination)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
addressSerializer.WriteAddrPort(request, c.destination)
|
||||
request.Write(b)
|
||||
_, err = c.Stream.Write(request.Bytes())
|
||||
_, err = c.stream.Write(request.Bytes())
|
||||
if err != nil {
|
||||
c.parent.closeWithError(E.Cause(err, "create new connection"))
|
||||
return 0, baderror.WrapQUIC(err)
|
||||
@@ -289,13 +286,17 @@ func (c *clientConn) Write(b []byte) (n int, err error) {
|
||||
c.requestWritten = true
|
||||
return len(b), nil
|
||||
}
|
||||
n, err = c.Stream.Write(b)
|
||||
n, err = c.stream.Write(b)
|
||||
return n, baderror.WrapQUIC(err)
|
||||
}
|
||||
|
||||
func (c *clientConn) Close() error {
|
||||
c.Stream.CancelRead(0)
|
||||
return c.Stream.Close()
|
||||
stream := c.stream
|
||||
if stream == nil {
|
||||
return nil
|
||||
}
|
||||
stream.CancelRead(0)
|
||||
return stream.Close()
|
||||
}
|
||||
|
||||
func (c *clientConn) LocalAddr() net.Addr {
|
||||
@@ -305,3 +306,24 @@ func (c *clientConn) LocalAddr() net.Addr {
|
||||
func (c *clientConn) RemoteAddr() net.Addr {
|
||||
return c.destination
|
||||
}
|
||||
|
||||
func (c *clientConn) SetDeadline(t time.Time) error {
|
||||
if c.stream == nil {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
return c.stream.SetDeadline(t)
|
||||
}
|
||||
|
||||
func (c *clientConn) SetReadDeadline(t time.Time) error {
|
||||
if c.stream == nil {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
return c.stream.SetReadDeadline(t)
|
||||
}
|
||||
|
||||
func (c *clientConn) SetWriteDeadline(t time.Time) error {
|
||||
if c.stream == nil {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
return c.stream.SetWriteDeadline(t)
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func (c *Client) handleMessage(conn *clientQUICConnection, data []byte) error {
|
||||
}
|
||||
switch data[1] {
|
||||
case CommandPacket:
|
||||
message := allocMessage()
|
||||
message := udpMessagePool.Get().(*udpMessage)
|
||||
err := decodeUDPMessage(message, data[2:])
|
||||
if err != nil {
|
||||
message.release()
|
||||
@@ -84,7 +84,7 @@ func (c *Client) handleUniStream(conn *clientQUICConnection, stream quic.Receive
|
||||
return E.New("unknown command ", command)
|
||||
}
|
||||
reader := io.MultiReader(bufio.NewCachedReader(stream, buffer), stream)
|
||||
message := allocMessage()
|
||||
message := udpMessagePool.Get().(*udpMessage)
|
||||
err = readUDPMessage(message, reader)
|
||||
if err != nil {
|
||||
message.release()
|
||||
|
||||
@@ -17,7 +17,6 @@ import (
|
||||
"github.com/sagernet/sing/common/atomic"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/cache"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
)
|
||||
|
||||
@@ -27,16 +26,11 @@ var udpMessagePool = sync.Pool{
|
||||
},
|
||||
}
|
||||
|
||||
func allocMessage() *udpMessage {
|
||||
message := udpMessagePool.Get().(*udpMessage)
|
||||
message.referenced = true
|
||||
return message
|
||||
}
|
||||
|
||||
func releaseMessages(messages []*udpMessage) {
|
||||
for _, message := range messages {
|
||||
if message != nil {
|
||||
message.release()
|
||||
*message = udpMessage{}
|
||||
udpMessagePool.Put(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,13 +42,9 @@ type udpMessage struct {
|
||||
fragmentID uint8
|
||||
destination M.Socksaddr
|
||||
data *buf.Buffer
|
||||
referenced bool
|
||||
}
|
||||
|
||||
func (m *udpMessage) release() {
|
||||
if !m.referenced {
|
||||
return
|
||||
}
|
||||
*m = udpMessage{}
|
||||
udpMessagePool.Put(m)
|
||||
}
|
||||
@@ -92,7 +82,7 @@ func fragUDPMessage(message *udpMessage, maxPacketSize int) []*udpMessage {
|
||||
originPacket := message.data.Bytes()
|
||||
udpMTU := maxPacketSize - message.headerSize()
|
||||
for remaining := len(originPacket); remaining > 0; remaining -= udpMTU {
|
||||
fragment := allocMessage()
|
||||
fragment := udpMessagePool.Get().(*udpMessage)
|
||||
*fragment = *message
|
||||
if remaining > udpMTU {
|
||||
fragment.data = buf.As(originPacket[:udpMTU])
|
||||
@@ -215,15 +205,12 @@ func (c *udpPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr)
|
||||
if buffer.Len() > 0xffff {
|
||||
return quic.ErrMessageTooLarge(0xffff)
|
||||
}
|
||||
if !destination.IsValid() {
|
||||
return E.New("invalid destination address")
|
||||
}
|
||||
packetId := c.packetId.Add(1)
|
||||
if packetId > math.MaxUint16 {
|
||||
c.packetId.Store(0)
|
||||
packetId = 0
|
||||
}
|
||||
message := allocMessage()
|
||||
message := udpMessagePool.Get().(*udpMessage)
|
||||
*message = udpMessage{
|
||||
sessionID: c.sessionID,
|
||||
packetID: uint16(packetId),
|
||||
@@ -259,21 +246,17 @@ func (c *udpPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
if len(p) > 0xffff {
|
||||
return 0, quic.ErrMessageTooLarge(0xffff)
|
||||
}
|
||||
destination := M.SocksaddrFromNet(addr)
|
||||
if !destination.IsValid() {
|
||||
return 0, E.New("invalid destination address")
|
||||
}
|
||||
packetId := c.packetId.Add(1)
|
||||
if packetId > math.MaxUint16 {
|
||||
c.packetId.Store(0)
|
||||
packetId = 0
|
||||
}
|
||||
message := allocMessage()
|
||||
message := udpMessagePool.Get().(*udpMessage)
|
||||
*message = udpMessage{
|
||||
sessionID: c.sessionID,
|
||||
packetID: uint16(packetId),
|
||||
fragmentTotal: 1,
|
||||
destination: destination,
|
||||
destination: M.SocksaddrFromNet(addr),
|
||||
data: buf.As(p),
|
||||
}
|
||||
if !c.udpStream && c.needFragment() && len(p) > c.udpMTU {
|
||||
@@ -440,7 +423,7 @@ func (d *udpDefragger) feed(m *udpMessage) *udpMessage {
|
||||
if int(item.count) != len(item.messages) {
|
||||
return nil
|
||||
}
|
||||
newMessage := allocMessage()
|
||||
newMessage := udpMessagePool.Get().(*udpMessage)
|
||||
*newMessage = *item.messages[0]
|
||||
var dataLength uint16
|
||||
for _, message := range item.messages {
|
||||
@@ -455,7 +438,6 @@ func (d *udpDefragger) feed(m *udpMessage) *udpMessage {
|
||||
item.messages = nil
|
||||
return newMessage
|
||||
}
|
||||
item.messages = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/quic-go"
|
||||
"github.com/sagernet/sing-box/common/baderror"
|
||||
"github.com/sagernet/sing-box/common/qtls"
|
||||
"github.com/sagernet/sing-box/common/tls"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/auth"
|
||||
"github.com/sagernet/sing/common/baderror"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
@@ -267,7 +267,7 @@ func (s *serverSession) handleUniStream(stream quic.ReceiveStream) error {
|
||||
return s.connErr
|
||||
case <-s.authDone:
|
||||
}
|
||||
message := allocMessage()
|
||||
message := udpMessagePool.Get().(*udpMessage)
|
||||
err = readUDPMessage(message, io.MultiReader(bytes.NewReader(buffer.From(2)), stream))
|
||||
if err != nil {
|
||||
message.release()
|
||||
|
||||
@@ -37,7 +37,7 @@ func (s *serverSession) handleMessage(data []byte) error {
|
||||
}
|
||||
switch data[1] {
|
||||
case CommandPacket:
|
||||
message := allocMessage()
|
||||
message := udpMessagePool.Get().(*udpMessage)
|
||||
err := decodeUDPMessage(message, data[2:])
|
||||
if err != nil {
|
||||
message.release()
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/common/baderror"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/baderror"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
"github.com/sagernet/sing/common/rw"
|
||||
)
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/common/baderror"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/baderror"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/common/baderror"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/baderror"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
|
||||
@@ -150,10 +150,7 @@ func (c *Conn) Write(b []byte) (n int, err error) {
|
||||
|
||||
func (c *Conn) WriteBuffer(buffer *buf.Buffer) error {
|
||||
if !c.requestWritten {
|
||||
err := EncodeRequest(c.request, buf.With(buffer.ExtendHeader(RequestLen(c.request))))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
EncodeRequest(c.request, buf.With(buffer.ExtendHeader(RequestLen(c.request))))
|
||||
c.requestWritten = true
|
||||
}
|
||||
return c.ExtendedConn.WriteBuffer(buffer)
|
||||
@@ -162,11 +159,7 @@ func (c *Conn) WriteBuffer(buffer *buf.Buffer) error {
|
||||
func (c *Conn) WriteVectorised(buffers []*buf.Buffer) error {
|
||||
if !c.requestWritten {
|
||||
buffer := buf.NewSize(RequestLen(c.request))
|
||||
err := EncodeRequest(c.request, buffer)
|
||||
if err != nil {
|
||||
buffer.Release()
|
||||
return err
|
||||
}
|
||||
EncodeRequest(c.request, buffer)
|
||||
c.requestWritten = true
|
||||
return c.writer.WriteVectorised(append([]*buf.Buffer{buffer}, buffers...))
|
||||
}
|
||||
|
||||
@@ -156,17 +156,14 @@ func WriteRequest(writer io.Writer, request Request, payload []byte) error {
|
||||
)
|
||||
|
||||
if request.Command != vmess.CommandMux {
|
||||
err := vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
common.Must(vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination))
|
||||
}
|
||||
|
||||
common.Must1(buffer.Write(payload))
|
||||
return common.Error(writer.Write(buffer.Bytes()))
|
||||
}
|
||||
|
||||
func EncodeRequest(request Request, buffer *buf.Buffer) error {
|
||||
func EncodeRequest(request Request, buffer *buf.Buffer) {
|
||||
var requestLen int
|
||||
requestLen += 1 // version
|
||||
requestLen += 16 // uuid
|
||||
@@ -198,12 +195,8 @@ func EncodeRequest(request Request, buffer *buf.Buffer) error {
|
||||
)
|
||||
|
||||
if request.Command != vmess.CommandMux {
|
||||
err := vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
common.Must(vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RequestLen(request Request) int {
|
||||
@@ -258,12 +251,10 @@ func WritePacketRequest(writer io.Writer, request Request, payload []byte) error
|
||||
common.Must(common.Error(buffer.WriteString(request.Flow)))
|
||||
}
|
||||
|
||||
common.Must(buffer.WriteByte(vmess.CommandUDP))
|
||||
|
||||
err := vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
common.Must(
|
||||
buffer.WriteByte(vmess.CommandUDP),
|
||||
vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination),
|
||||
)
|
||||
|
||||
if len(payload) > 0 {
|
||||
common.Must(
|
||||
|
||||
Reference in New Issue
Block a user