Compare commits

...

18 Commits

Author SHA1 Message Date
世界
fe8d46cce5 Fix TFO async write 2023-09-09 19:52:13 +08:00
世界
b1f289bce5 Fix TUIC context 2023-09-09 11:41:04 +08:00
世界
a8beb80876 Update Makefile 2023-09-07 22:37:55 +08:00
世界
ff209471d8 Fix QUIC defragger 2023-09-07 21:35:25 +08:00
unknown
806f7d0a2b Fix QUIC stream usage 2023-09-07 21:34:36 +08:00
世界
6b943caf37 Reject invalid connection 2023-09-07 21:34:36 +08:00
世界
4ea2d460f4 Fix router close 2023-09-07 21:34:35 +08:00
世界
c84c18f960 platform: Fix crash on android 2023-09-07 21:34:35 +08:00
世界
1402bdab41 Fix connect domain for IP outbounds 2023-09-07 21:34:35 +08:00
renovate[bot]
7082cf277e [dependencies] Update actions/checkout action to v4 2023-09-07 21:34:35 +08:00
世界
b9310154a7 clash-api: Move default mode to first 2023-09-07 21:34:35 +08:00
世界
55c34e3fb0 platform: Improve client 2023-09-07 21:34:35 +08:00
世界
68f2202eec documentation: Bump version 2023-08-31 23:32:44 +08:00
renovate[bot]
5057e50bb8 [dependencies] Update actions/stale action to v8
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-31 23:32:44 +08:00
世界
23e1a69955 Update Makefile 2023-08-31 23:32:44 +08:00
世界
b83c6c9d20 Fix return nil addr in conn 2023-08-30 21:28:03 +08:00
世界
67deac6d44 Fix hysteria packet write 2023-08-30 18:23:17 +08:00
世界
ea3731162b Update Makefile 2023-08-30 18:23:17 +08:00
39 changed files with 422 additions and 234 deletions

View File

@@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Get latest go version - name: Get latest go version
@@ -48,7 +48,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Setup Go - name: Setup Go
@@ -68,7 +68,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Setup Go - name: Setup Go
@@ -199,7 +199,7 @@ jobs:
TAGS: with_clash_api,with_quic TAGS: with_clash_api,with_quic
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Get latest go version - name: Get latest go version

View File

@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
- name: Setup Docker Buildx - name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@v2
- name: Setup QEMU for Docker Buildx - name: Setup QEMU for Docker Buildx

View File

@@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Get latest go version - name: Get latest go version

View File

@@ -8,7 +8,7 @@ jobs:
stale: stale:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/stale@v7 - uses: actions/stale@v8
with: with:
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days' stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days'
days-before-stale: 60 days-before-stale: 60

View File

@@ -69,12 +69,19 @@ release_install:
go install -v github.com/goreleaser/goreleaser@latest go install -v github.com/goreleaser/goreleaser@latest
go install -v github.com/tcnksm/ghr@latest go install -v github.com/tcnksm/ghr@latest
upload_android: update_android_version:
go run ./cmd/internal/update_android_version go run ./cmd/internal/update_android_version
build_android:
cd ../sing-box-for-android && ./gradlew :app:assembleRelease cd ../sing-box-for-android && ./gradlew :app:assembleRelease
mkdir dist/release_android
upload_android:
mkdir -p dist/release_android
cp ../sing-box-for-android/app/build/outputs/apk/release/*.apk dist/release_android cp ../sing-box-for-android/app/build/outputs/apk/release/*.apk dist/release_android
ghr --replace --draft --prerelease -p 3 "v${VERSION}" dist/release_android ghr --replace --draft --prerelease -p 3 "v${VERSION}" dist/release_android
rm -rf dist/release_android
release_android: lib_android update_android_version build_android upload_android
publish_android: publish_android:
cd ../sing-box-for-android && ./gradlew :app:appCenterAssembleAndUploadRelease cd ../sing-box-for-android && ./gradlew :app:appCenterAssembleAndUploadRelease
@@ -110,8 +117,12 @@ notarize_macos_independent:
cd ../sing-box-for-apple && \ cd ../sing-box-for-apple && \
xcodebuild -exportArchive -archivePath "build/SFM.System.xcarchive" -exportOptionsPlist SFM.System/Upload.plist xcodebuild -exportArchive -archivePath "build/SFM.System.xcarchive" -exportOptionsPlist SFM.System/Upload.plist
wait_notarize_macos_independent:
sleep 60
export_macos_independent: export_macos_independent:
rm -rf dist/SFM rm -rf dist/SFM
mkdir -p dist/SFM
cd ../sing-box-for-apple && \ cd ../sing-box-for-apple && \
xcodebuild -exportNotarizedApp -archivePath build/SFM.System.xcarchive -exportPath "../sing-box/dist/SFM" xcodebuild -exportNotarizedApp -archivePath build/SFM.System.xcarchive -exportPath "../sing-box/dist/SFM"
@@ -121,7 +132,7 @@ upload_macos_independent:
zip -ry "SFM-${VERSION}-universal.zip" SFM.app && \ zip -ry "SFM-${VERSION}-universal.zip" SFM.app && \
ghr --replace --draft --prerelease "v${VERSION}" *.zip ghr --replace --draft --prerelease "v${VERSION}" *.zip
release_macos_independent: build_macos_independent notarize_macos_independent export_macos_independent upload_macos_independent release_macos_independent: build_macos_independent notarize_macos_independent wait_notarize_macos_independent export_macos_independent upload_macos_independent
build_tvos: build_tvos:
cd ../sing-box-for-apple && \ cd ../sing-box-for-apple && \
@@ -138,7 +149,11 @@ release_tvos: build_tvos upload_tvos_app_store
update_apple_version: update_apple_version:
go run ./cmd/internal/update_apple_version go run ./cmd/internal/update_apple_version
release_apple: update_apple_version release_ios release_macos release_macos_independent release_tvos release_apple: lib_ios update_apple_version release_ios release_macos release_tvos release_macos_independent
rm -rf dist
release_apple_beta: update_apple_version release_ios release_macos release_tvos
rm -rf dist
test: test:
@go test -v ./... && \ @go test -v ./... && \

View File

@@ -2,6 +2,7 @@ package build_shared
import ( import (
"github.com/sagernet/sing-box/common/badversion" "github.com/sagernet/sing-box/common/badversion"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/shell" "github.com/sagernet/sing/common/shell"
) )
@@ -22,11 +23,14 @@ func ReadTag() (string, error) {
return version.String() + "-" + shortCommit, nil return version.String() + "-" + shortCommit, nil
} }
func ReadTagVersion() (string, error) { func ReadTagVersion() (badversion.Version, error) {
currentTagRev, err := shell.Exec("git", "describe", "--tags", "--abbrev=0").ReadOutput() currentTag := common.Must1(shell.Exec("git", "describe", "--tags").ReadOutput())
if err != nil { currentTagRev := common.Must1(shell.Exec("git", "describe", "--tags", "--abbrev=0").ReadOutput())
return "", err
}
version := badversion.Parse(currentTagRev[1:]) version := badversion.Parse(currentTagRev[1:])
return version.VersionString(), nil if currentTagRev != currentTag {
if version.PreReleaseIdentifier == "" {
version.Patch++
}
}
return version, nil
} }

View File

@@ -12,7 +12,7 @@ import (
) )
func main() { func main() {
newTag := common.Must1(build_shared.ReadTag()) newVersion := common.Must1(build_shared.ReadTagVersion())
androidPath, err := filepath.Abs("../sing-box-for-android") androidPath, err := filepath.Abs("../sing-box-for-android")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@@ -25,12 +25,12 @@ func main() {
} }
for _, propPair := range propsList { for _, propPair := range propsList {
if propPair[0] == "VERSION_NAME" { if propPair[0] == "VERSION_NAME" {
if propPair[1] == newTag { if propPair[1] == newVersion.String() {
log.Info("version not changed") log.Info("version not changed")
return return
} }
propPair[1] = newTag propPair[1] = newVersion.String()
log.Info("updated version to ", newTag) log.Info("updated version to ", newVersion.String())
} }
} }
for _, propPair := range propsList { for _, propPair := range propsList {
@@ -40,7 +40,7 @@ func main() {
propPair[1] = strconv.Itoa(int(versionCode + 1)) propPair[1] = strconv.Itoa(int(versionCode + 1))
log.Info("updated version code to ", propPair[1]) log.Info("updated version code to ", propPair[1])
case "RELEASE_NOTES": case "RELEASE_NOTES":
propPair[1] = "sing-box " + newTag propPair[1] = "sing-box " + newVersion.String()
} }
} }
var newProps []string var newProps []string

View File

@@ -15,7 +15,6 @@ import (
func main() { func main() {
newVersion := common.Must1(build_shared.ReadTagVersion()) newVersion := common.Must1(build_shared.ReadTagVersion())
newTag := common.Must1(build_shared.ReadTag())
applePath, err := filepath.Abs("../sing-box-for-apple") applePath, err := filepath.Abs("../sing-box-for-apple")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@@ -27,10 +26,10 @@ func main() {
common.Must(decoder.Decode(&project)) common.Must(decoder.Decode(&project))
objectsMap := project["objects"].(map[string]any) objectsMap := project["objects"].(map[string]any)
projectContent := string(common.Must1(os.ReadFile("sing-box.xcodeproj/project.pbxproj"))) projectContent := string(common.Must1(os.ReadFile("sing-box.xcodeproj/project.pbxproj")))
newContent, updated0 := findAndReplace(objectsMap, projectContent, []string{"io.nekohasekai.sfa"}, newVersion) 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"}, newTag) newContent, updated1 := findAndReplace(objectsMap, newContent, []string{"io.nekohasekai.sfa.independent", "io.nekohasekai.sfa.system"}, newVersion.String())
if updated0 || updated1 { if updated0 || updated1 {
log.Info("updated version to ", newTag) 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.bak", []byte(projectContent), 0o644))
common.Must(os.WriteFile("sing-box.xcodeproj/project.pbxproj", []byte(newContent), 0o644)) common.Must(os.WriteFile("sing-box.xcodeproj/project.pbxproj", []byte(newContent), 0o644))
} else { } else {
@@ -44,6 +43,10 @@ func findAndReplace(objectsMap map[string]any, projectContent string, bundleIDLi
for _, objectKey := range objectKeyList { for _, objectKey := range objectKeyList {
matchRegexp := common.Must1(regexp.Compile(objectKey + ".*= \\{")) matchRegexp := common.Must1(regexp.Compile(objectKey + ".*= \\{"))
indexes := matchRegexp.FindStringIndex(projectContent) indexes := matchRegexp.FindStringIndex(projectContent)
if len(indexes) < 2 {
println(projectContent)
log.Fatal("failed to find object key ", objectKey, ": ", strings.Index(projectContent, objectKey))
}
indexStart := indexes[1] indexStart := indexes[1]
indexEnd := indexStart + strings.Index(projectContent[indexStart:], "}") indexEnd := indexStart + strings.Index(projectContent[indexStart:], "}")
versionStart := indexStart + strings.Index(projectContent[indexStart:indexEnd], "MARKETING_VERSION = ") + 20 versionStart := indexStart + strings.Index(projectContent[indexStart:indexEnd], "MARKETING_VERSION = ") + 20
@@ -53,7 +56,7 @@ func findAndReplace(objectsMap map[string]any, projectContent string, bundleIDLi
continue continue
} }
updated = true updated = true
projectContent = projectContent[indexStart:versionStart] + newVersion + projectContent[versionEnd:indexEnd] projectContent = projectContent[:versionStart] + newVersion + projectContent[versionEnd:]
} }
return projectContent, updated return projectContent, updated
} }

View File

@@ -1,62 +0,0 @@
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
}

View File

@@ -7,6 +7,7 @@ import (
"io" "io"
"net" "net"
"os" "os"
"sync"
"time" "time"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
@@ -24,6 +25,7 @@ type slowOpenConn struct {
destination M.Socksaddr destination M.Socksaddr
conn net.Conn conn net.Conn
create chan struct{} create chan struct{}
access sync.Mutex
err error err error
} }
@@ -60,16 +62,26 @@ func (c *slowOpenConn) Read(b []byte) (n int, err error) {
} }
func (c *slowOpenConn) Write(b []byte) (n int, err error) { func (c *slowOpenConn) Write(b []byte) (n int, err error) {
if c.conn == nil { if c.conn != nil {
c.conn, err = c.dialer.DialContext(c.ctx, c.network, c.destination.String(), b) return c.conn.Write(b)
if err != nil {
c.conn = nil
c.err = E.Cause(err, "dial tcp fast open")
}
close(c.create)
return
} }
return c.conn.Write(b) c.access.Lock()
defer c.access.Unlock()
select {
case <-c.create:
if c.err != nil {
return 0, c.err
}
return c.conn.Write(b)
default:
}
c.conn, err = c.dialer.DialContext(c.ctx, c.network, c.destination.String(), b)
if err != nil {
c.conn = nil
c.err = E.Cause(err, "dial tcp fast open")
}
close(c.create)
return
} }
func (c *slowOpenConn) Close() error { func (c *slowOpenConn) Close() error {

View File

@@ -1,3 +1,7 @@
#### 1.4.1
* Fixes and improvements
#### 1.4.0 #### 1.4.0
* Fix bugs and update dependencies * Fix bugs and update dependencies

View File

@@ -90,7 +90,7 @@ func NewServer(ctx context.Context, router adapter.Router, logFactory log.Observ
defaultMode = options.DefaultMode defaultMode = options.DefaultMode
} }
if !common.Contains(server.modeList, defaultMode) { if !common.Contains(server.modeList, defaultMode) {
server.modeList = append(server.modeList, defaultMode) server.modeList = append([]string{defaultMode}, server.modeList...)
} }
server.mode = defaultMode server.mode = defaultMode
if options.StoreMode || options.StoreSelected || options.StoreFakeIP || options.ExternalController == "" { if options.StoreMode || options.StoreSelected || options.StoreFakeIP || options.ExternalController == "" {

View File

@@ -11,4 +11,6 @@ const (
CommandGroupExpand CommandGroupExpand
CommandClashMode CommandClashMode
CommandSetClashMode CommandSetClashMode
CommandGetSystemProxyStatus
CommandSetSystemProxyEnabled
) )

View File

@@ -5,6 +5,7 @@ import (
"net" "net"
"os" "os"
"path/filepath" "path/filepath"
"time"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
@@ -53,9 +54,24 @@ 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 { func (c *CommandClient) Connect() error {
common.Close(c.conn) common.Close(c.conn)
conn, err := c.directConnect() conn, err := c.directConnectWithRetry()
if err != nil { if err != nil {
return err return err
} }

View File

@@ -35,6 +35,8 @@ type CommandServer struct {
type CommandServerHandler interface { type CommandServerHandler interface {
ServiceReload() error ServiceReload() error
GetSystemProxyStatus() *SystemProxyStatus
SetSystemProxyEnabled(isEnabled bool) error
} }
func NewCommandServer(handler CommandServerHandler, maxLines int32) *CommandServer { func NewCommandServer(handler CommandServerHandler, maxLines int32) *CommandServer {
@@ -159,6 +161,10 @@ func (s *CommandServer) handleConnection(conn net.Conn) error {
return s.handleModeConn(conn) return s.handleModeConn(conn)
case CommandSetClashMode: case CommandSetClashMode:
return s.handleSetClashMode(conn) return s.handleSetClashMode(conn)
case CommandGetSystemProxyStatus:
return s.handleGetSystemProxyStatus(conn)
case CommandSetSystemProxyEnabled:
return s.handleSetSystemProxyEnabled(conn)
default: default:
return E.New("unknown command: ", command) return E.New("unknown command: ", command)
} }

View File

@@ -0,0 +1,82 @@
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)
}

View File

@@ -4,6 +4,7 @@ package libbox
import ( import (
"os" "os"
"runtime"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
@@ -18,12 +19,14 @@ func RedirectStderr(path string) error {
if err != nil { if err != nil {
return err return err
} }
if sUserID > 0 { if runtime.GOOS != "android" {
err = outputFile.Chown(sUserID, sGroupID) if sUserID > 0 {
if err != nil { err = outputFile.Chown(sUserID, sGroupID)
outputFile.Close() if err != nil {
os.Remove(outputFile.Name()) outputFile.Close()
return err os.Remove(outputFile.Name())
return err
}
} }
} }
err = unix.Dup2(int(outputFile.Fd()), int(os.Stderr.Fd())) err = unix.Dup2(int(outputFile.Fd()), int(os.Stderr.Fd()))

12
go.mod
View File

@@ -25,14 +25,14 @@ require (
github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2 github.com/sagernet/gvisor v0.0.0-20230627031050-1ab0276e0dd2
github.com/sagernet/quic-go v0.0.0-20230825040534-0cd917b2ddda github.com/sagernet/quic-go v0.0.0-20230825040534-0cd917b2ddda
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
github.com/sagernet/sing v0.2.10-0.20230824115837-8d731e68853a github.com/sagernet/sing v0.2.10-0.20230907044649-03c21c0a1205
github.com/sagernet/sing-dns v0.1.9-0.20230824120133-4d5cbceb40c1 github.com/sagernet/sing-dns v0.1.9-0.20230824120133-4d5cbceb40c1
github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c github.com/sagernet/sing-mux v0.1.3-0.20230907005326-7befbadbf314
github.com/sagernet/sing-shadowsocks v0.2.4 github.com/sagernet/sing-shadowsocks v0.2.5-0.20230907005610-126234728ca0
github.com/sagernet/sing-shadowsocks2 v0.1.3 github.com/sagernet/sing-shadowsocks2 v0.1.4-0.20230907005906-5d2917b29248
github.com/sagernet/sing-shadowtls v0.1.4 github.com/sagernet/sing-shadowtls v0.1.4
github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641 github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641
github.com/sagernet/sing-vmess v0.1.7 github.com/sagernet/sing-vmess v0.1.8-0.20230907010359-161fb0ac716b
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2
@@ -50,6 +50,7 @@ require (
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
google.golang.org/grpc v1.57.0 google.golang.org/grpc v1.57.0
google.golang.org/protobuf v1.31.0 google.golang.org/protobuf v1.31.0
howett.net/plist v1.0.0
) )
//replace github.com/sagernet/sing => ../sing //replace github.com/sagernet/sing => ../sing
@@ -93,6 +94,5 @@ require (
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
howett.net/plist v1.0.0 // indirect
lukechampine.com/blake3 v1.2.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect
) )

20
go.sum
View File

@@ -114,22 +114,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/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.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.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
github.com/sagernet/sing v0.2.10-0.20230824115837-8d731e68853a h1:eV4HEz9NP7eAlQ/IHD6OF2VVM6ke4Vw6htuSAsvgtDk= github.com/sagernet/sing v0.2.10-0.20230907044649-03c21c0a1205 h1:U/OwMlCH1XFjrDrw5BESGxGsnynT6nDnHvNI9Xv0U78=
github.com/sagernet/sing v0.2.10-0.20230824115837-8d731e68853a/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA= github.com/sagernet/sing v0.2.10-0.20230907044649-03c21c0a1205/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 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-dns v0.1.9-0.20230824120133-4d5cbceb40c1/go.mod h1:Kg98PBJEg/08jsNFtmZWmPomhskn9Ausn50ecNm4M+8=
github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c h1:35/FowAvt3Z62mck0TXzVc4jS5R5CWq62qcV2P1cp0I= github.com/sagernet/sing-mux v0.1.3-0.20230907005326-7befbadbf314 h1:P5+NZGMH8KSI3L8lKw1znxdRi0tIpWbGYjmv8GrFHrQ=
github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY= github.com/sagernet/sing-mux v0.1.3-0.20230907005326-7befbadbf314/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY=
github.com/sagernet/sing-shadowsocks v0.2.4 h1:s/CqXlvFAZhlIoHWUwPw5CoNnQ9Ibki9pckjuugtVfY= github.com/sagernet/sing-shadowsocks v0.2.5-0.20230907005610-126234728ca0 h1:9wHYWxH+fcs01PM2+DylA8LNNY3ElnZykQo9rysng8U=
github.com/sagernet/sing-shadowsocks v0.2.4/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM= github.com/sagernet/sing-shadowsocks v0.2.5-0.20230907005610-126234728ca0/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM=
github.com/sagernet/sing-shadowsocks2 v0.1.3 h1:WXoLvCFi5JTFBRYorf1YePGYIQyJ/zbsBM6Fwbl5kGA= github.com/sagernet/sing-shadowsocks2 v0.1.4-0.20230907005906-5d2917b29248 h1:JTFfy/LDmVFEK4KZJEujmC1iO8+aoF4unYhhZZRzRq4=
github.com/sagernet/sing-shadowsocks2 v0.1.3/go.mod h1:DOhJc/cLeqRv0wuePrQso+iUmDxOnWF4eT/oMcRzYFw= github.com/sagernet/sing-shadowsocks2 v0.1.4-0.20230907005906-5d2917b29248/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 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4= 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 h1:a8lktNrCWZJisB+nPraW+qB73ZofgPtGmlfqNYcO79g=
github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641/go.mod h1:+YImslQMLgMQcVgZZ9IK4ue1o/605VSU90amHUcp4hA= github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641/go.mod h1:+YImslQMLgMQcVgZZ9IK4ue1o/605VSU90amHUcp4hA=
github.com/sagernet/sing-vmess v0.1.7 h1:TM8FFLsXmlXH9XT8/oDgc6PC5BOzrg6OzyEe01is2r4= github.com/sagernet/sing-vmess v0.1.8-0.20230907010359-161fb0ac716b h1:2ezfJtH5JosiEwJhVa+rimQ6ps/t2+7h+mOzMoiaZnA=
github.com/sagernet/sing-vmess v0.1.7/go.mod h1:1qkC1L1T2sxnS/NuO6HU72S8TkltV+EXoKGR29m/Yss= github.com/sagernet/sing-vmess v0.1.8-0.20230907010359-161fb0ac716b/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 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37/go.mod h1:3skNSftZDJWTGVtVaM2jfbce8qHnmH/AGDRe62iNOg0= 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= github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 h1:Px+hN4Vzgx+iCGVnWH5A8eR7JhNnIV3rGQmBxA7cw6Q=

View File

@@ -582,7 +582,7 @@ func (c *naiveH2Conn) Close() error {
} }
func (c *naiveH2Conn) LocalAddr() net.Addr { func (c *naiveH2Conn) LocalAddr() net.Addr {
return nil return M.Socksaddr{}
} }
func (c *naiveH2Conn) RemoteAddr() net.Addr { func (c *naiveH2Conn) RemoteAddr() net.Addr {

View File

@@ -70,6 +70,28 @@ func NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata a
return CopyEarlyConn(ctx, conn, outConn) 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.HandshakeFailure(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.HandshakeFailure(conn, err)
}
return CopyEarlyConn(ctx, conn, outConn)
}
func NewPacketConnection(ctx context.Context, this N.Dialer, conn N.PacketConn, metadata adapter.InboundContext) error { func NewPacketConnection(ctx context.Context, this N.Dialer, conn N.PacketConn, metadata adapter.InboundContext) error {
ctx = adapter.WithContext(ctx, &metadata) ctx = adapter.WithContext(ctx, &metadata)
var outConn net.PacketConn var outConn net.PacketConn
@@ -99,6 +121,42 @@ func NewPacketConnection(ctx context.Context, this N.Dialer, conn N.PacketConn,
return bufio.CopyPacketConn(ctx, conn, bufio.NewPacketConn(outConn)) 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.HandshakeFailure(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.HandshakeFailure(conn, 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 CopyEarlyConn(ctx context.Context, conn net.Conn, serverConn net.Conn) error { func CopyEarlyConn(ctx context.Context, conn net.Conn, serverConn net.Conn) error {
if cachedReader, isCached := conn.(N.CachedReader); isCached { if cachedReader, isCached := conn.(N.CachedReader); isCached {
payload := cachedReader.ReadCached() payload := cachedReader.ReadCached()

View File

@@ -80,11 +80,11 @@ func (h *Socks) DialContext(ctx context.Context, network string, destination M.S
return nil, E.Extend(N.ErrUnknownNetwork, network) return nil, E.Extend(N.ErrUnknownNetwork, network)
} }
if h.resolve && destination.IsFqdn() { if h.resolve && destination.IsFqdn() {
addrs, err := h.router.LookupDefault(ctx, destination.Fqdn) destinationAddresses, err := h.router.LookupDefault(ctx, destination.Fqdn)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return N.DialSerial(ctx, h.client, network, destination, addrs) return N.DialSerial(ctx, h.client, network, destination, destinationAddresses)
} }
return h.client.DialContext(ctx, network, destination) return h.client.DialContext(ctx, network, destination)
} }
@@ -97,14 +97,25 @@ func (h *Socks) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.
h.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination) h.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination)
return h.uotClient.ListenPacket(ctx, 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) h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
return h.client.ListenPacket(ctx, destination) return h.client.ListenPacket(ctx, destination)
} }
func (h *Socks) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { func (h *Socks) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
return NewConnection(ctx, h, conn, metadata) return NewDirectConnection(ctx, h.router, h, conn, metadata)
} }
func (h *Socks) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { func (h *Socks) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
return NewPacketConnection(ctx, h, conn, metadata) return NewDirectPacketConnection(ctx, h.router, h, conn, metadata)
} }

View File

@@ -202,26 +202,37 @@ func (w *WireGuard) DialContext(ctx context.Context, network string, destination
w.logger.InfoContext(ctx, "outbound packet connection to ", destination) w.logger.InfoContext(ctx, "outbound packet connection to ", destination)
} }
if destination.IsFqdn() { if destination.IsFqdn() {
addrs, err := w.router.LookupDefault(ctx, destination.Fqdn) destinationAddresses, err := w.router.LookupDefault(ctx, destination.Fqdn)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return N.DialSerial(ctx, w.tunDevice, network, destination, addrs) return N.DialSerial(ctx, w.tunDevice, network, destination, destinationAddresses)
} }
return w.tunDevice.DialContext(ctx, network, destination) return w.tunDevice.DialContext(ctx, network, destination)
} }
func (w *WireGuard) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { func (w *WireGuard) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
w.logger.InfoContext(ctx, "outbound packet connection to ", destination) 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) return w.tunDevice.ListenPacket(ctx, destination)
} }
func (w *WireGuard) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { func (w *WireGuard) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
return NewConnection(ctx, w, conn, metadata) return NewDirectConnection(ctx, w.router, w, conn, metadata)
} }
func (w *WireGuard) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { func (w *WireGuard) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
return NewPacketConnection(ctx, w, conn, metadata) return NewDirectPacketConnection(ctx, w.router, w, conn, metadata)
} }
func (w *WireGuard) Start() error { func (w *WireGuard) Start() error {

View File

@@ -521,7 +521,7 @@ func (r *Router) Close() error {
return E.Cause(err, "close dns transport[", i, "]") return E.Cause(err, "close dns transport[", i, "]")
}) })
} }
if r.geositeReader != nil { if r.geoIPReader != nil {
r.logger.Trace("closing geoip reader") r.logger.Trace("closing geoip reader")
err = E.Append(err, common.Close(r.geoIPReader), func(err error) error { err = E.Append(err, common.Close(r.geoIPReader), func(err error) error {
return E.Cause(err, "close geoip reader") return E.Cause(err, "close geoip reader")

View File

@@ -10,9 +10,9 @@ require (
github.com/docker/docker v24.0.5+incompatible github.com/docker/docker v24.0.5+incompatible
github.com/docker/go-connections v0.4.0 github.com/docker/go-connections v0.4.0
github.com/gofrs/uuid/v5 v5.0.0 github.com/gofrs/uuid/v5 v5.0.0
github.com/sagernet/sing v0.2.10-0.20230824115837-8d731e68853a github.com/sagernet/sing v0.2.10-0.20230907044649-03c21c0a1205
github.com/sagernet/sing-shadowsocks v0.2.4 github.com/sagernet/sing-shadowsocks v0.2.5-0.20230907005610-126234728ca0
github.com/sagernet/sing-shadowsocks2 v0.1.3 github.com/sagernet/sing-shadowsocks2 v0.1.4-0.20230907005906-5d2917b29248
github.com/spyzhov/ajson v0.9.0 github.com/spyzhov/ajson v0.9.0
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
go.uber.org/goleak v1.2.1 go.uber.org/goleak v1.2.1
@@ -73,10 +73,10 @@ require (
github.com/sagernet/quic-go v0.0.0-20230825040534-0cd917b2ddda // indirect github.com/sagernet/quic-go v0.0.0-20230825040534-0cd917b2ddda // indirect
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // 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-dns v0.1.9-0.20230824120133-4d5cbceb40c1 // indirect
github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c // indirect github.com/sagernet/sing-mux v0.1.3-0.20230907005326-7befbadbf314 // indirect
github.com/sagernet/sing-shadowtls v0.1.4 // 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-tun v0.1.12-0.20230821065522-7545dc2d5641 // indirect
github.com/sagernet/sing-vmess v0.1.7 // indirect github.com/sagernet/sing-vmess v0.1.8-0.20230907010359-161fb0ac716b // indirect
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 // 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/tfo-go v0.0.0-20230816093905-5a5c285d44a6 // indirect
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 // indirect github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 // indirect

View File

@@ -113,8 +113,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI= github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM=
github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 h1:KyhtFFt1Jtp5vW2ohNvstvQffTOQ/s5vENuGXzdA+TM= github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 h1:KyhtFFt1Jtp5vW2ohNvstvQffTOQ/s5vENuGXzdA+TM=
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0/go.mod h1:D4SFEOkJK+4W1v86ZhX0jPM0rAL498fyQAChqMtes/I= github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0/go.mod h1:D4SFEOkJK+4W1v86ZhX0jPM0rAL498fyQAChqMtes/I=
@@ -124,31 +123,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/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 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/quic-go v0.0.0-20230824033040-30ef72e3be3e h1:URg7GQT9Mp0b6m/LXH1NgVT3P/ybVomvy2kkfA6QIHQ= github.com/sagernet/quic-go v0.0.0-20230825040534-0cd917b2ddda h1:7J/hnOFqCThiCrVpvr0wKO+Dic/XPSulPr5yI8FVJMs=
github.com/sagernet/quic-go v0.0.0-20230824033040-30ef72e3be3e/go.mod h1:7DXnweBVxZ7CQWsCdc7QAAQ65dFPEtenfz+w6WDESlI=
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-20230825040534-0cd917b2ddda/go.mod h1:Iw8Tt3dMqC/61cMHa0nN5i/958oYuuMnQCMOSPx+xcg=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc= 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/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.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.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
github.com/sagernet/sing v0.2.10-0.20230821073500-620f3a3b882d h1:4kgoOCE48CuQcBUcoRnE0QTPXkl8yM8i7Nipmzp/978= github.com/sagernet/sing v0.2.10-0.20230907044649-03c21c0a1205 h1:U/OwMlCH1XFjrDrw5BESGxGsnynT6nDnHvNI9Xv0U78=
github.com/sagernet/sing v0.2.10-0.20230821073500-620f3a3b882d/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA= github.com/sagernet/sing v0.2.10-0.20230907044649-03c21c0a1205/go.mod h1:9uOZwWkhT2Z2WldolLxX34s+1svAX4i4vvz5hy8u1MA=
github.com/sagernet/sing v0.2.10-0.20230824115837-8d731e68853a/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.20230731012726-ad50da89b659 h1:1DAKccGNqTYJ8nsBR765FS0LVBVXfuFlFAHqKsGN3EI=
github.com/sagernet/sing-dns v0.1.9-0.20230731012726-ad50da89b659/go.mod h1:W7GHTZFS8RkoLI3bA2LFY27/0E+uoQESWtMFLepO/JA=
github.com/sagernet/sing-dns v0.1.9-0.20230824120133-4d5cbceb40c1/go.mod h1:Kg98PBJEg/08jsNFtmZWmPomhskn9Ausn50ecNm4M+8= 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.20230811111955-dc1639b5204c h1:35/FowAvt3Z62mck0TXzVc4jS5R5CWq62qcV2P1cp0I= github.com/sagernet/sing-mux v0.1.3-0.20230907005326-7befbadbf314 h1:P5+NZGMH8KSI3L8lKw1znxdRi0tIpWbGYjmv8GrFHrQ=
github.com/sagernet/sing-mux v0.1.3-0.20230811111955-dc1639b5204c/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY= github.com/sagernet/sing-mux v0.1.3-0.20230907005326-7befbadbf314/go.mod h1:TKxqIvfQQgd36jp2tzsPavGjYTVZilV+atip1cssjIY=
github.com/sagernet/sing-shadowsocks v0.2.4 h1:s/CqXlvFAZhlIoHWUwPw5CoNnQ9Ibki9pckjuugtVfY= github.com/sagernet/sing-shadowsocks v0.2.5-0.20230907005610-126234728ca0 h1:9wHYWxH+fcs01PM2+DylA8LNNY3ElnZykQo9rysng8U=
github.com/sagernet/sing-shadowsocks v0.2.4/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM= github.com/sagernet/sing-shadowsocks v0.2.5-0.20230907005610-126234728ca0/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM=
github.com/sagernet/sing-shadowsocks2 v0.1.3 h1:WXoLvCFi5JTFBRYorf1YePGYIQyJ/zbsBM6Fwbl5kGA= github.com/sagernet/sing-shadowsocks2 v0.1.4-0.20230907005906-5d2917b29248 h1:JTFfy/LDmVFEK4KZJEujmC1iO8+aoF4unYhhZZRzRq4=
github.com/sagernet/sing-shadowsocks2 v0.1.3/go.mod h1:DOhJc/cLeqRv0wuePrQso+iUmDxOnWF4eT/oMcRzYFw= github.com/sagernet/sing-shadowsocks2 v0.1.4-0.20230907005906-5d2917b29248/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 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4= 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 h1:a8lktNrCWZJisB+nPraW+qB73ZofgPtGmlfqNYcO79g=
github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641/go.mod h1:+YImslQMLgMQcVgZZ9IK4ue1o/605VSU90amHUcp4hA= github.com/sagernet/sing-tun v0.1.12-0.20230821065522-7545dc2d5641/go.mod h1:+YImslQMLgMQcVgZZ9IK4ue1o/605VSU90amHUcp4hA=
github.com/sagernet/sing-vmess v0.1.7 h1:TM8FFLsXmlXH9XT8/oDgc6PC5BOzrg6OzyEe01is2r4= github.com/sagernet/sing-vmess v0.1.8-0.20230907010359-161fb0ac716b h1:2ezfJtH5JosiEwJhVa+rimQ6ps/t2+7h+mOzMoiaZnA=
github.com/sagernet/sing-vmess v0.1.7/go.mod h1:1qkC1L1T2sxnS/NuO6HU72S8TkltV+EXoKGR29m/Yss= github.com/sagernet/sing-vmess v0.1.8-0.20230907010359-161fb0ac716b/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 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37/go.mod h1:3skNSftZDJWTGVtVaM2jfbce8qHnmH/AGDRe62iNOg0= 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= github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 h1:Px+hN4Vzgx+iCGVnWH5A8eR7JhNnIV3rGQmBxA7cw6Q=
@@ -190,8 +186,7 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
go4.org/netipx v0.0.0-20230728184502-ec4c8b891b28 h1:zLxFnORHDFTSkJPawMU7LzsuGQJ4MUFS653jJHpORow= go4.org/netipx v0.0.0-20230824141953-6213f710f925 h1:eeQDDVKFkx0g4Hyy8pHgmZaK0EqB4SD6rvKbUdN3ziQ=
go4.org/netipx v0.0.0-20230728184502-ec4c8b891b28/go.mod h1:TQvodOM+hJTioNQJilmLXu08JNb8i+ccq418+KWu1/Y=
go4.org/netipx v0.0.0-20230824141953-6213f710f925/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= go4.org/netipx v0.0.0-20230824141953-6213f710f925/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=

View File

@@ -394,7 +394,7 @@ func (c *Conn) Read(p []byte) (n int, err error) {
} }
func (c *Conn) LocalAddr() net.Addr { func (c *Conn) LocalAddr() net.Addr {
return nil return M.Socksaddr{}
} }
func (c *Conn) RemoteAddr() net.Addr { func (c *Conn) RemoteAddr() net.Addr {
@@ -502,7 +502,7 @@ func (c *PacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
} }
func (c *PacketConn) LocalAddr() net.Addr { func (c *PacketConn) LocalAddr() net.Addr {
return nil return M.Socksaddr{}
} }
func (c *PacketConn) RemoteAddr() net.Addr { func (c *PacketConn) RemoteAddr() net.Addr {
@@ -526,11 +526,12 @@ func (c *PacketConn) NeedAdditionalReadDeadline() bool {
} }
func (c *PacketConn) Read(b []byte) (n int, err error) { func (c *PacketConn) Read(b []byte) (n int, err error) {
return 0, os.ErrInvalid n, _, err = c.ReadFrom(b)
return
} }
func (c *PacketConn) Write(b []byte) (n int, err error) { func (c *PacketConn) Write(b []byte) (n int, err error) {
return 0, os.ErrInvalid return c.WriteTo(b, c.destination)
} }
func (c *PacketConn) Close() error { func (c *PacketConn) Close() error {

View File

@@ -6,8 +6,8 @@ import (
"syscall" "syscall"
"github.com/sagernet/quic-go" "github.com/sagernet/quic-go"
"github.com/sagernet/sing-box/common/baderror"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/baderror"
) )
type PacketConnWrapper struct { type PacketConnWrapper struct {

View File

@@ -204,10 +204,13 @@ func ClientHandshake(conn net.Conn, key [KeyLength]byte, destination M.Socksaddr
common.Must1(header.Write(key[:])) common.Must1(header.Write(key[:]))
common.Must1(header.Write(CRLF)) common.Must1(header.Write(CRLF))
common.Must(header.WriteByte(CommandTCP)) common.Must(header.WriteByte(CommandTCP))
common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination)) err := M.SocksaddrSerializer.WriteAddrPort(header, destination)
if err != nil {
return err
}
common.Must1(header.Write(CRLF)) common.Must1(header.Write(CRLF))
common.Must1(header.Write(payload)) common.Must1(header.Write(payload))
_, err := conn.Write(header.Bytes()) _, err = conn.Write(header.Bytes())
if err != nil { if err != nil {
return E.Cause(err, "write request") return E.Cause(err, "write request")
} }
@@ -219,10 +222,13 @@ func ClientHandshakeBuffer(conn net.Conn, key [KeyLength]byte, destination M.Soc
common.Must1(header.Write(key[:])) common.Must1(header.Write(key[:]))
common.Must1(header.Write(CRLF)) common.Must1(header.Write(CRLF))
common.Must(header.WriteByte(CommandTCP)) common.Must(header.WriteByte(CommandTCP))
common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination)) err := M.SocksaddrSerializer.WriteAddrPort(header, destination)
if err != nil {
return err
}
common.Must1(header.Write(CRLF)) common.Must1(header.Write(CRLF))
_, err := conn.Write(payload.Bytes()) _, err = conn.Write(payload.Bytes())
if err != nil { if err != nil {
return E.Cause(err, "write request") return E.Cause(err, "write request")
} }
@@ -244,7 +250,10 @@ func ClientHandshakePacket(conn net.Conn, key [KeyLength]byte, destination M.Soc
common.Must1(header.Write(key[:])) common.Must1(header.Write(key[:]))
common.Must1(header.Write(CRLF)) common.Must1(header.Write(CRLF))
common.Must(header.WriteByte(CommandUDP)) common.Must(header.WriteByte(CommandUDP))
common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination)) err := M.SocksaddrSerializer.WriteAddrPort(header, destination)
if err != nil {
return err
}
common.Must1(header.Write(CRLF)) common.Must1(header.Write(CRLF))
common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination)) common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination))
common.Must(binary.Write(header, binary.BigEndian, uint16(payloadLen))) common.Must(binary.Write(header, binary.BigEndian, uint16(payloadLen)))
@@ -257,7 +266,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 { if err != nil {
return E.Cause(err, "write payload") return E.Cause(err, "write payload")
} }
@@ -289,10 +298,13 @@ func WritePacket(conn net.Conn, buffer *buf.Buffer, destination M.Socksaddr) err
defer buffer.Release() defer buffer.Release()
bufferLen := buffer.Len() bufferLen := buffer.Len()
header := buf.With(buffer.ExtendHeader(M.SocksaddrSerializer.AddrPortLen(destination) + 4)) header := buf.With(buffer.ExtendHeader(M.SocksaddrSerializer.AddrPortLen(destination) + 4))
common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination)) err := M.SocksaddrSerializer.WriteAddrPort(header, destination)
if err != nil {
return err
}
common.Must(binary.Write(header, binary.BigEndian, uint16(bufferLen))) common.Must(binary.Write(header, binary.BigEndian, uint16(bufferLen)))
common.Must1(header.Write(CRLF)) common.Must1(header.Write(CRLF))
_, err := conn.Write(buffer.Bytes()) _, err = conn.Write(buffer.Bytes())
if err != nil { if err != nil {
return E.Cause(err, "write packet") return E.Cause(err, "write packet")
} }

View File

@@ -5,14 +5,13 @@ import (
"crypto/tls" "crypto/tls"
"io" "io"
"net" "net"
"os"
"runtime" "runtime"
"sync" "sync"
"time" "time"
"github.com/sagernet/quic-go" "github.com/sagernet/quic-go"
"github.com/sagernet/sing-box/common/baderror"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/baderror"
"github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio" "github.com/sagernet/sing/common/bufio"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
@@ -103,7 +102,7 @@ func (c *Client) offer(ctx context.Context) (*clientQUICConnection, error) {
} }
func (c *Client) offerNew(ctx context.Context) (*clientQUICConnection, error) { func (c *Client) offerNew(ctx context.Context) (*clientQUICConnection, error) {
udpConn, err := c.dialer.DialContext(ctx, "udp", c.serverAddr) udpConn, err := c.dialer.DialContext(c.ctx, "udp", c.serverAddr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -184,8 +183,8 @@ func (c *Client) DialConn(ctx context.Context, destination M.Socksaddr) (net.Con
return nil, err return nil, err
} }
return &clientConn{ return &clientConn{
Stream: stream,
parent: conn, parent: conn,
stream: stream,
destination: destination, destination: destination,
}, nil }, nil
} }
@@ -253,8 +252,8 @@ func (c *clientQUICConnection) closeWithError(err error) {
} }
type clientConn struct { type clientConn struct {
quic.Stream
parent *clientQUICConnection parent *clientQUICConnection
stream quic.Stream
destination M.Socksaddr destination M.Socksaddr
requestWritten bool requestWritten bool
} }
@@ -264,18 +263,22 @@ func (c *clientConn) NeedHandshake() bool {
} }
func (c *clientConn) Read(b []byte) (n int, err error) { 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) return n, baderror.WrapQUIC(err)
} }
func (c *clientConn) Write(b []byte) (n int, err error) { func (c *clientConn) Write(b []byte) (n int, err error) {
if !c.requestWritten { if !c.requestWritten {
request := buf.NewSize(2 + addressSerializer.AddrPortLen(c.destination) + len(b)) request := buf.NewSize(2 + addressSerializer.AddrPortLen(c.destination) + len(b))
defer request.Release()
request.WriteByte(Version) request.WriteByte(Version)
request.WriteByte(CommandConnect) request.WriteByte(CommandConnect)
addressSerializer.WriteAddrPort(request, c.destination) err = addressSerializer.WriteAddrPort(request, c.destination)
if err != nil {
return
}
request.Write(b) request.Write(b)
_, err = c.stream.Write(request.Bytes()) _, err = c.Stream.Write(request.Bytes())
if err != nil { if err != nil {
c.parent.closeWithError(E.Cause(err, "create new connection")) c.parent.closeWithError(E.Cause(err, "create new connection"))
return 0, baderror.WrapQUIC(err) return 0, baderror.WrapQUIC(err)
@@ -283,17 +286,13 @@ func (c *clientConn) Write(b []byte) (n int, err error) {
c.requestWritten = true c.requestWritten = true
return len(b), nil return len(b), nil
} }
n, err = c.stream.Write(b) n, err = c.Stream.Write(b)
return n, baderror.WrapQUIC(err) return n, baderror.WrapQUIC(err)
} }
func (c *clientConn) Close() error { func (c *clientConn) Close() error {
stream := c.stream c.Stream.CancelRead(0)
if stream == nil { return c.Stream.Close()
return nil
}
stream.CancelRead(0)
return stream.Close()
} }
func (c *clientConn) LocalAddr() net.Addr { func (c *clientConn) LocalAddr() net.Addr {
@@ -303,24 +302,3 @@ func (c *clientConn) LocalAddr() net.Addr {
func (c *clientConn) RemoteAddr() net.Addr { func (c *clientConn) RemoteAddr() net.Addr {
return c.destination 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)
}

View File

@@ -34,7 +34,7 @@ func (c *Client) handleMessage(conn *clientQUICConnection, data []byte) error {
} }
switch data[1] { switch data[1] {
case CommandPacket: case CommandPacket:
message := udpMessagePool.Get().(*udpMessage) message := allocMessage()
err := decodeUDPMessage(message, data[2:]) err := decodeUDPMessage(message, data[2:])
if err != nil { if err != nil {
message.release() message.release()
@@ -82,7 +82,7 @@ func (c *Client) handleUniStream(conn *clientQUICConnection, stream quic.Receive
return E.New("unknown command ", command) return E.New("unknown command ", command)
} }
reader := io.MultiReader(bufio.NewCachedReader(stream, buffer), stream) reader := io.MultiReader(bufio.NewCachedReader(stream, buffer), stream)
message := udpMessagePool.Get().(*udpMessage) message := allocMessage()
err = readUDPMessage(message, reader) err = readUDPMessage(message, reader)
if err != nil { if err != nil {
message.release() message.release()

View File

@@ -17,6 +17,7 @@ import (
"github.com/sagernet/sing/common/atomic" "github.com/sagernet/sing/common/atomic"
"github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/cache" "github.com/sagernet/sing/common/cache"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata" M "github.com/sagernet/sing/common/metadata"
) )
@@ -26,11 +27,16 @@ var udpMessagePool = sync.Pool{
}, },
} }
func allocMessage() *udpMessage {
message := udpMessagePool.Get().(*udpMessage)
message.referenced = true
return message
}
func releaseMessages(messages []*udpMessage) { func releaseMessages(messages []*udpMessage) {
for _, message := range messages { for _, message := range messages {
if message != nil { if message != nil {
*message = udpMessage{} message.release()
udpMessagePool.Put(message)
} }
} }
} }
@@ -42,9 +48,13 @@ type udpMessage struct {
fragmentID uint8 fragmentID uint8
destination M.Socksaddr destination M.Socksaddr
data *buf.Buffer data *buf.Buffer
referenced bool
} }
func (m *udpMessage) release() { func (m *udpMessage) release() {
if !m.referenced {
return
}
*m = udpMessage{} *m = udpMessage{}
udpMessagePool.Put(m) udpMessagePool.Put(m)
} }
@@ -82,7 +92,7 @@ func fragUDPMessage(message *udpMessage, maxPacketSize int) []*udpMessage {
originPacket := message.data.Bytes() originPacket := message.data.Bytes()
udpMTU := maxPacketSize - message.headerSize() udpMTU := maxPacketSize - message.headerSize()
for remaining := len(originPacket); remaining > 0; remaining -= udpMTU { for remaining := len(originPacket); remaining > 0; remaining -= udpMTU {
fragment := udpMessagePool.Get().(*udpMessage) fragment := allocMessage()
*fragment = *message *fragment = *message
if remaining > udpMTU { if remaining > udpMTU {
fragment.data = buf.As(originPacket[:udpMTU]) fragment.data = buf.As(originPacket[:udpMTU])
@@ -205,12 +215,15 @@ func (c *udpPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr)
if buffer.Len() > 0xffff { if buffer.Len() > 0xffff {
return quic.ErrMessageTooLarge(0xffff) return quic.ErrMessageTooLarge(0xffff)
} }
if !destination.IsValid() {
return E.New("invalid destination address")
}
packetId := c.packetId.Add(1) packetId := c.packetId.Add(1)
if packetId > math.MaxUint16 { if packetId > math.MaxUint16 {
c.packetId.Store(0) c.packetId.Store(0)
packetId = 0 packetId = 0
} }
message := udpMessagePool.Get().(*udpMessage) message := allocMessage()
*message = udpMessage{ *message = udpMessage{
sessionID: c.sessionID, sessionID: c.sessionID,
packetID: uint16(packetId), packetID: uint16(packetId),
@@ -246,17 +259,21 @@ func (c *udpPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
if len(p) > 0xffff { if len(p) > 0xffff {
return 0, quic.ErrMessageTooLarge(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) packetId := c.packetId.Add(1)
if packetId > math.MaxUint16 { if packetId > math.MaxUint16 {
c.packetId.Store(0) c.packetId.Store(0)
packetId = 0 packetId = 0
} }
message := udpMessagePool.Get().(*udpMessage) message := allocMessage()
*message = udpMessage{ *message = udpMessage{
sessionID: c.sessionID, sessionID: c.sessionID,
packetID: uint16(packetId), packetID: uint16(packetId),
fragmentTotal: 1, fragmentTotal: 1,
destination: M.SocksaddrFromNet(addr), destination: destination,
data: buf.As(p), data: buf.As(p),
} }
if !c.udpStream && c.needFragment() && len(p) > c.udpMTU { if !c.udpStream && c.needFragment() && len(p) > c.udpMTU {
@@ -423,7 +440,7 @@ func (d *udpDefragger) feed(m *udpMessage) *udpMessage {
if int(item.count) != len(item.messages) { if int(item.count) != len(item.messages) {
return nil return nil
} }
newMessage := udpMessagePool.Get().(*udpMessage) newMessage := allocMessage()
*newMessage = *item.messages[0] *newMessage = *item.messages[0]
var dataLength uint16 var dataLength uint16
for _, message := range item.messages { for _, message := range item.messages {
@@ -438,6 +455,7 @@ func (d *udpDefragger) feed(m *udpMessage) *udpMessage {
item.messages = nil item.messages = nil
return newMessage return newMessage
} }
item.messages = nil
return nil return nil
} }

View File

@@ -13,9 +13,9 @@ import (
"time" "time"
"github.com/sagernet/quic-go" "github.com/sagernet/quic-go"
"github.com/sagernet/sing-box/common/baderror"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/auth" "github.com/sagernet/sing/common/auth"
"github.com/sagernet/sing/common/baderror"
"github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio" "github.com/sagernet/sing/common/bufio"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
@@ -264,7 +264,7 @@ func (s *serverSession) handleUniStream(stream quic.ReceiveStream) error {
return s.connErr return s.connErr
case <-s.authDone: case <-s.authDone:
} }
message := udpMessagePool.Get().(*udpMessage) message := allocMessage()
err = readUDPMessage(message, io.MultiReader(bytes.NewReader(buffer.From(2)), stream)) err = readUDPMessage(message, io.MultiReader(bytes.NewReader(buffer.From(2)), stream))
if err != nil { if err != nil {
message.release() message.release()

View File

@@ -35,7 +35,7 @@ func (s *serverSession) handleMessage(data []byte) error {
} }
switch data[1] { switch data[1] {
case CommandPacket: case CommandPacket:
message := udpMessagePool.Get().(*udpMessage) message := allocMessage()
err := decodeUDPMessage(message, data[2:]) err := decodeUDPMessage(message, data[2:])
if err != nil { if err != nil {
message.release() message.release()

View File

@@ -5,8 +5,9 @@ import (
"os" "os"
"time" "time"
"github.com/sagernet/sing-box/common/baderror"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/baderror"
M "github.com/sagernet/sing/common/metadata"
"github.com/sagernet/sing/common/rw" "github.com/sagernet/sing/common/rw"
) )
@@ -62,11 +63,11 @@ func (c *GRPCConn) Close() error {
} }
func (c *GRPCConn) LocalAddr() net.Addr { func (c *GRPCConn) LocalAddr() net.Addr {
return nil return M.Socksaddr{}
} }
func (c *GRPCConn) RemoteAddr() net.Addr { func (c *GRPCConn) RemoteAddr() net.Addr {
return nil return M.Socksaddr{}
} }
func (c *GRPCConn) SetDeadline(t time.Time) error { func (c *GRPCConn) SetDeadline(t time.Time) error {

View File

@@ -11,10 +11,11 @@ import (
"sync" "sync"
"time" "time"
"github.com/sagernet/sing-box/common/baderror"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/baderror"
"github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio" "github.com/sagernet/sing/common/bufio"
M "github.com/sagernet/sing/common/metadata"
"github.com/sagernet/sing/common/rw" "github.com/sagernet/sing/common/rw"
) )
@@ -138,7 +139,7 @@ func (c *GunConn) Close() error {
} }
func (c *GunConn) LocalAddr() net.Addr { func (c *GunConn) LocalAddr() net.Addr {
return nil return M.Socksaddr{}
} }
func (c *GunConn) RemoteAddr() net.Addr { func (c *GunConn) RemoteAddr() net.Addr {

View File

@@ -10,12 +10,13 @@ import (
"sync" "sync"
"time" "time"
"github.com/sagernet/sing-box/common/baderror"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/baderror"
"github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio" "github.com/sagernet/sing/common/bufio"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format" F "github.com/sagernet/sing/common/format"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
) )
@@ -174,11 +175,11 @@ func (c *HTTP2Conn) Close() error {
} }
func (c *HTTP2Conn) LocalAddr() net.Addr { func (c *HTTP2Conn) LocalAddr() net.Addr {
return nil return M.Socksaddr{}
} }
func (c *HTTP2Conn) RemoteAddr() net.Addr { func (c *HTTP2Conn) RemoteAddr() net.Addr {
return nil return M.Socksaddr{}
} }
func (c *HTTP2Conn) SetDeadline(t time.Time) error { func (c *HTTP2Conn) SetDeadline(t time.Time) error {

View File

@@ -150,7 +150,10 @@ func (c *Conn) Write(b []byte) (n int, err error) {
func (c *Conn) WriteBuffer(buffer *buf.Buffer) error { func (c *Conn) WriteBuffer(buffer *buf.Buffer) error {
if !c.requestWritten { if !c.requestWritten {
EncodeRequest(c.request, buf.With(buffer.ExtendHeader(RequestLen(c.request)))) err := EncodeRequest(c.request, buf.With(buffer.ExtendHeader(RequestLen(c.request))))
if err != nil {
return err
}
c.requestWritten = true c.requestWritten = true
} }
return c.ExtendedConn.WriteBuffer(buffer) return c.ExtendedConn.WriteBuffer(buffer)
@@ -159,7 +162,11 @@ func (c *Conn) WriteBuffer(buffer *buf.Buffer) error {
func (c *Conn) WriteVectorised(buffers []*buf.Buffer) error { func (c *Conn) WriteVectorised(buffers []*buf.Buffer) error {
if !c.requestWritten { if !c.requestWritten {
buffer := buf.NewSize(RequestLen(c.request)) buffer := buf.NewSize(RequestLen(c.request))
EncodeRequest(c.request, buffer) err := EncodeRequest(c.request, buffer)
if err != nil {
buffer.Release()
return err
}
c.requestWritten = true c.requestWritten = true
return c.writer.WriteVectorised(append([]*buf.Buffer{buffer}, buffers...)) return c.writer.WriteVectorised(append([]*buf.Buffer{buffer}, buffers...))
} }

View File

@@ -156,14 +156,17 @@ func WriteRequest(writer io.Writer, request Request, payload []byte) error {
) )
if request.Command != vmess.CommandMux { if request.Command != vmess.CommandMux {
common.Must(vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination)) err := vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination)
if err != nil {
return err
}
} }
common.Must1(buffer.Write(payload)) common.Must1(buffer.Write(payload))
return common.Error(writer.Write(buffer.Bytes())) return common.Error(writer.Write(buffer.Bytes()))
} }
func EncodeRequest(request Request, buffer *buf.Buffer) { func EncodeRequest(request Request, buffer *buf.Buffer) error {
var requestLen int var requestLen int
requestLen += 1 // version requestLen += 1 // version
requestLen += 16 // uuid requestLen += 16 // uuid
@@ -195,8 +198,12 @@ func EncodeRequest(request Request, buffer *buf.Buffer) {
) )
if request.Command != vmess.CommandMux { if request.Command != vmess.CommandMux {
common.Must(vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination)) err := vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination)
if err != nil {
return err
}
} }
return nil
} }
func RequestLen(request Request) int { func RequestLen(request Request) int {
@@ -251,10 +258,12 @@ func WritePacketRequest(writer io.Writer, request Request, payload []byte) error
common.Must(common.Error(buffer.WriteString(request.Flow))) common.Must(common.Error(buffer.WriteString(request.Flow)))
} }
common.Must( common.Must(buffer.WriteByte(vmess.CommandUDP))
buffer.WriteByte(vmess.CommandUDP),
vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination), err := vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination)
) if err != nil {
return err
}
if len(payload) > 0 { if len(payload) > 0 {
common.Must( common.Must(