mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-04-12 01:57:18 +10:00
Compare commits
19 Commits
v1.3-beta2
...
v1.2.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de1b5971e1 | ||
|
|
5c20d0b4d5 | ||
|
|
9df96ac7f1 | ||
|
|
87cd925144 | ||
|
|
fecb796000 | ||
|
|
cfb6c804aa | ||
|
|
11c50c7558 | ||
|
|
34cc7f176e | ||
|
|
b54da9c6af | ||
|
|
f44f86b832 | ||
|
|
4ebf40f582 | ||
|
|
53e4302143 | ||
|
|
cf778eda4f | ||
|
|
bb63429079 | ||
|
|
f7f9a7ae20 | ||
|
|
8699412a4c | ||
|
|
0d7aa19cd1 | ||
|
|
50a7295360 | ||
|
|
e57b6ae98d |
12
.github/workflows/debug.yml
vendored
12
.github/workflows/debug.yml
vendored
@@ -31,12 +31,6 @@ jobs:
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: ${{ steps.version.outputs.go_version }}
|
||||
- name: Cache go module
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/go/pkg/mod
|
||||
key: go-${{ hashFiles('**/go.sum') }}
|
||||
- name: Add cache to Go proxy
|
||||
run: |
|
||||
version=`git rev-parse HEAD`
|
||||
@@ -196,12 +190,6 @@ jobs:
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: ${{ steps.version.outputs.go_version }}
|
||||
- name: Cache go module
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/go/pkg/mod
|
||||
key: go-${{ hashFiles('**/go.sum') }}
|
||||
- name: Build
|
||||
id: build
|
||||
run: make
|
||||
|
||||
6
.github/workflows/lint.yml
vendored
6
.github/workflows/lint.yml
vendored
@@ -31,12 +31,6 @@ jobs:
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: ${{ steps.version.outputs.go_version }}
|
||||
- name: Cache go module
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/go/pkg/mod
|
||||
key: go-${{ hashFiles('**/go.sum') }}
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
|
||||
13
Makefile
13
Makefile
@@ -77,13 +77,20 @@ test_stdio:
|
||||
go mod tidy && \
|
||||
go test -v -tags "$(TAGS_TEST),force_stdio" .
|
||||
|
||||
android:
|
||||
go run ./cmd/internal/build_libbox -target android
|
||||
|
||||
ios:
|
||||
go run ./cmd/internal/build_libbox -target ios
|
||||
|
||||
lib:
|
||||
go run ./cmd/internal/build_libbox
|
||||
go run ./cmd/internal/build_libbox -target android
|
||||
go run ./cmd/internal/build_libbox -target ios
|
||||
|
||||
lib_install:
|
||||
go get -v -d
|
||||
go install -v github.com/sagernet/gomobile/cmd/gomobile@v0.0.0-20221130124640-349ebaa752ca
|
||||
go install -v github.com/sagernet/gomobile/cmd/gobind@v0.0.0-20221130124640-349ebaa752ca
|
||||
go install -v github.com/sagernet/gomobile/cmd/gomobile@v0.0.0-20230413023804-244d7ff07035
|
||||
go install -v github.com/sagernet/gomobile/cmd/gobind@v0.0.0-20230413023804-244d7ff07035
|
||||
|
||||
clean:
|
||||
rm -rf bin dist sing-box
|
||||
|
||||
@@ -8,6 +8,10 @@ The universal proxy platform.
|
||||
|
||||
https://sing-box.sagernet.org
|
||||
|
||||
## Support
|
||||
|
||||
https://community.sagernet.org/c/sing-box/
|
||||
|
||||
## License
|
||||
|
||||
```
|
||||
|
||||
@@ -12,7 +12,7 @@ type Conn struct {
|
||||
element *list.Element[io.Closer]
|
||||
}
|
||||
|
||||
func NewConn(conn net.Conn) (*Conn, error) {
|
||||
func NewConn(conn net.Conn) (net.Conn, error) {
|
||||
connAccess.Lock()
|
||||
element := openConnection.PushBack(conn)
|
||||
connAccess.Unlock()
|
||||
|
||||
@@ -12,7 +12,7 @@ type PacketConn struct {
|
||||
element *list.Element[io.Closer]
|
||||
}
|
||||
|
||||
func NewPacketConn(conn net.PacketConn) (*PacketConn, error) {
|
||||
func NewPacketConn(conn net.PacketConn) (net.PacketConn, error) {
|
||||
connAccess.Lock()
|
||||
element := openConnection.PushBack(conn)
|
||||
connAccess.Unlock()
|
||||
|
||||
@@ -73,7 +73,7 @@ func (d *ResolveDialer) ListenPacket(ctx context.Context, destination M.Socksadd
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bufio.NewNATPacketConn(bufio.NewPacketConn(conn), destination, M.SocksaddrFrom(destinationAddress, destination.Port)), nil
|
||||
return bufio.NewNATPacketConn(bufio.NewPacketConn(conn), M.SocksaddrFrom(destinationAddress, destination.Port), destination), nil
|
||||
}
|
||||
|
||||
func (d *ResolveDialer) Upstream() any {
|
||||
|
||||
@@ -413,7 +413,11 @@ func (c *ClientPacketAddrConn) ReadFrom(p []byte) (n int, addr net.Addr, err err
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
addr = destination.UDPAddr()
|
||||
if destination.IsFqdn() {
|
||||
addr = destination
|
||||
} else {
|
||||
addr = destination.UDPAddr()
|
||||
}
|
||||
var length uint16
|
||||
err = binary.Read(c.ExtendedConn, binary.BigEndian, &length)
|
||||
if err != nil {
|
||||
|
||||
@@ -3,10 +3,12 @@ package process
|
||||
import (
|
||||
"context"
|
||||
"net/netip"
|
||||
"os/user"
|
||||
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-tun"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
F "github.com/sagernet/sing/common/format"
|
||||
)
|
||||
|
||||
type Searcher interface {
|
||||
@@ -28,5 +30,15 @@ type Info struct {
|
||||
}
|
||||
|
||||
func FindProcessInfo(searcher Searcher, ctx context.Context, network string, source netip.AddrPort, destination netip.AddrPort) (*Info, error) {
|
||||
return findProcessInfo(searcher, ctx, network, source, destination)
|
||||
info, err := searcher.FindProcessInfo(ctx, network, source, destination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if info.UserId != -1 {
|
||||
osUser, _ := user.LookupId(F.ToString(info.UserId))
|
||||
if osUser != nil {
|
||||
info.User = osUser.Username
|
||||
}
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
//go:build linux && !android
|
||||
|
||||
package process
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/netip"
|
||||
"os/user"
|
||||
|
||||
F "github.com/sagernet/sing/common/format"
|
||||
)
|
||||
|
||||
func findProcessInfo(searcher Searcher, ctx context.Context, network string, source netip.AddrPort, destination netip.AddrPort) (*Info, error) {
|
||||
info, err := searcher.FindProcessInfo(ctx, network, source, destination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if info.UserId != -1 {
|
||||
osUser, _ := user.LookupId(F.ToString(info.UserId))
|
||||
if osUser != nil {
|
||||
info.User = osUser.Username
|
||||
}
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
//go:build !linux || android
|
||||
|
||||
package process
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
func findProcessInfo(searcher Searcher, ctx context.Context, network string, source netip.AddrPort, destination netip.AddrPort) (*Info, error) {
|
||||
return searcher.FindProcessInfo(ctx, network, source, destination)
|
||||
}
|
||||
@@ -24,12 +24,12 @@ func PeekStream(ctx context.Context, conn net.Conn, buffer *buf.Buffer, timeout
|
||||
}
|
||||
err := conn.SetReadDeadline(time.Now().Add(timeout))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, E.Cause(err, "set read deadline")
|
||||
}
|
||||
_, err = buffer.ReadOnceFrom(conn)
|
||||
err = E.Errors(err, conn.SetReadDeadline(time.Time{}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, E.Cause(err, "read payload")
|
||||
}
|
||||
var metadata *adapter.InboundContext
|
||||
var errors []error
|
||||
|
||||
@@ -180,7 +180,7 @@ func NewSTDServer(ctx context.Context, router adapter.Router, logger log.Logger,
|
||||
tlsConfig.ServerName = options.ServerName
|
||||
}
|
||||
if len(options.ALPN) > 0 {
|
||||
tlsConfig.NextProtos = append(tlsConfig.NextProtos, options.ALPN...)
|
||||
tlsConfig.NextProtos = append(options.ALPN, tlsConfig.NextProtos...)
|
||||
}
|
||||
if options.MinVersion != "" {
|
||||
minVersion, err := ParseTLSVersion(options.MinVersion)
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
#### 1.2.4
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.2.3
|
||||
|
||||
* Introducing our [new Android client application](/installation/clients/sfa)
|
||||
|
||||
@@ -4,32 +4,26 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/experimental/clashapi/compatible"
|
||||
|
||||
"go.uber.org/atomic"
|
||||
"github.com/sagernet/sing/common/atomic"
|
||||
)
|
||||
|
||||
type Manager struct {
|
||||
connections compatible.Map[string, tracker]
|
||||
uploadTemp *atomic.Int64
|
||||
downloadTemp *atomic.Int64
|
||||
uploadBlip *atomic.Int64
|
||||
downloadBlip *atomic.Int64
|
||||
uploadTotal *atomic.Int64
|
||||
downloadTotal *atomic.Int64
|
||||
ticker *time.Ticker
|
||||
done chan struct{}
|
||||
uploadTemp atomic.Int64
|
||||
downloadTemp atomic.Int64
|
||||
uploadBlip atomic.Int64
|
||||
downloadBlip atomic.Int64
|
||||
uploadTotal atomic.Int64
|
||||
downloadTotal atomic.Int64
|
||||
|
||||
connections compatible.Map[string, tracker]
|
||||
ticker *time.Ticker
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
func NewManager() *Manager {
|
||||
manager := &Manager{
|
||||
uploadTemp: atomic.NewInt64(0),
|
||||
downloadTemp: atomic.NewInt64(0),
|
||||
uploadBlip: atomic.NewInt64(0),
|
||||
downloadBlip: atomic.NewInt64(0),
|
||||
uploadTotal: atomic.NewInt64(0),
|
||||
downloadTotal: atomic.NewInt64(0),
|
||||
ticker: time.NewTicker(time.Second),
|
||||
done: make(chan struct{}),
|
||||
ticker: time.NewTicker(time.Second),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
go manager.handle()
|
||||
return manager
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package trafficontrol
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net"
|
||||
"net/netip"
|
||||
"time"
|
||||
@@ -8,10 +9,10 @@ import (
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/experimental/trackerconn"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/atomic"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
"go.uber.org/atomic"
|
||||
"github.com/gofrs/uuid/v5"
|
||||
)
|
||||
|
||||
type Metadata struct {
|
||||
@@ -43,6 +44,19 @@ type trackerInfo struct {
|
||||
RulePayload string `json:"rulePayload"`
|
||||
}
|
||||
|
||||
func (t trackerInfo) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(map[string]any{
|
||||
"id": t.UUID.String(),
|
||||
"metadata": t.Metadata,
|
||||
"upload": t.UploadTotal.Load(),
|
||||
"download": t.DownloadTotal.Load(),
|
||||
"start": t.Start,
|
||||
"chains": t.Chain,
|
||||
"rule": t.Rule,
|
||||
"rulePayload": t.RulePayload,
|
||||
})
|
||||
}
|
||||
|
||||
type tcpTracker struct {
|
||||
N.ExtendedConn `json:"-"`
|
||||
*trackerInfo
|
||||
@@ -97,8 +111,8 @@ func NewTCPTracker(conn net.Conn, manager *Manager, metadata Metadata, router ad
|
||||
next = group.Now()
|
||||
}
|
||||
|
||||
upload := atomic.NewInt64(0)
|
||||
download := atomic.NewInt64(0)
|
||||
upload := new(atomic.Int64)
|
||||
download := new(atomic.Int64)
|
||||
|
||||
t := &tcpTracker{
|
||||
ExtendedConn: trackerconn.NewHook(conn, func(n int64) {
|
||||
@@ -184,8 +198,8 @@ func NewUDPTracker(conn N.PacketConn, manager *Manager, metadata Metadata, route
|
||||
next = group.Now()
|
||||
}
|
||||
|
||||
upload := atomic.NewInt64(0)
|
||||
download := atomic.NewInt64(0)
|
||||
upload := new(atomic.Int64)
|
||||
download := new(atomic.Int64)
|
||||
|
||||
ut := &udpTracker{
|
||||
PacketConn: trackerconn.NewHookPacket(conn, func(n int64) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/debug"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/observable"
|
||||
"github.com/sagernet/sing/common/x/list"
|
||||
@@ -71,7 +72,9 @@ func (s *CommandServer) loopConnection(listener net.Listener) {
|
||||
go func() {
|
||||
hErr := s.handleConnection(conn)
|
||||
if hErr != nil && !E.IsClosed(err) {
|
||||
log.Warn("log-server: process connection: ", hErr)
|
||||
if debug.Enabled {
|
||||
log.Warn("log-server: process connection: ", hErr)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ func (s *CommandServer) handleStatusConn(conn net.Conn) error {
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
return ctx.Err()
|
||||
case <-ticker.C:
|
||||
}
|
||||
}
|
||||
|
||||
29
experimental/libbox/log.go
Normal file
29
experimental/libbox/log.go
Normal file
@@ -0,0 +1,29 @@
|
||||
//go:build darwin || linux
|
||||
|
||||
package libbox
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var stderrFile *os.File
|
||||
|
||||
func RedirectStderr(path string) error {
|
||||
if stats, err := os.Stat(path); err == nil && stats.Size() > 0 {
|
||||
_ = os.Rename(path, path+".old")
|
||||
}
|
||||
outputFile, err := os.Create(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = unix.Dup2(int(outputFile.Fd()), int(os.Stderr.Fd()))
|
||||
if err != nil {
|
||||
outputFile.Close()
|
||||
os.Remove(outputFile.Name())
|
||||
return err
|
||||
}
|
||||
stderrFile = outputFile
|
||||
return nil
|
||||
}
|
||||
@@ -3,11 +3,10 @@ package trackerconn
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/sagernet/sing/common/atomic"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
"go.uber.org/atomic"
|
||||
)
|
||||
|
||||
func New(conn net.Conn, readCounter []*atomic.Int64, writeCounter []*atomic.Int64) *Conn {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package trackerconn
|
||||
|
||||
import (
|
||||
"github.com/sagernet/sing/common/atomic"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
"go.uber.org/atomic"
|
||||
)
|
||||
|
||||
func NewPacket(conn N.PacketConn, readCounter []*atomic.Int64, writeCounter []*atomic.Int64) *PacketConn {
|
||||
|
||||
@@ -12,10 +12,9 @@ import (
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/experimental/trackerconn"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing/common/atomic"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
"go.uber.org/atomic"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -211,7 +210,7 @@ func (s *StatsService) loadOrCreateCounter(name string) *atomic.Int64 {
|
||||
if loaded {
|
||||
return counter
|
||||
}
|
||||
counter = atomic.NewInt64(0)
|
||||
counter = &atomic.Int64{}
|
||||
s.counters[name] = counter
|
||||
return counter
|
||||
}
|
||||
|
||||
15
go.mod
15
go.mod
@@ -4,7 +4,7 @@ go 1.18
|
||||
|
||||
require (
|
||||
berty.tech/go-libtor v1.0.385
|
||||
github.com/Dreamacro/clash v1.14.0
|
||||
github.com/Dreamacro/clash v1.15.0
|
||||
github.com/caddyserver/certmagic v0.17.2
|
||||
github.com/cretz/bine v0.2.0
|
||||
github.com/dustin/go-humanize v1.0.1
|
||||
@@ -13,8 +13,9 @@ require (
|
||||
github.com/go-chi/cors v1.2.1
|
||||
github.com/go-chi/render v1.0.2
|
||||
github.com/gofrs/uuid v4.4.0+incompatible
|
||||
github.com/gofrs/uuid/v5 v5.0.0
|
||||
github.com/hashicorp/yamux v0.1.1
|
||||
github.com/insomniacslk/dhcp v0.0.0-20230327135226-74ae03f2425e
|
||||
github.com/insomniacslk/dhcp v0.0.0-20230407062729-974c6f05fe16
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible
|
||||
github.com/mholt/acmez v1.1.0
|
||||
github.com/miekg/dns v1.1.53
|
||||
@@ -22,11 +23,11 @@ require (
|
||||
github.com/oschwald/maxminddb-golang v1.10.0
|
||||
github.com/pires/go-proxyproto v0.7.0
|
||||
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0
|
||||
github.com/sagernet/gomobile v0.0.0-20221130124640-349ebaa752ca
|
||||
github.com/sagernet/gomobile v0.0.0-20230413023804-244d7ff07035
|
||||
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
|
||||
github.com/sagernet/sing v0.2.2-0.20230407053809-308e421e33c2
|
||||
github.com/sagernet/sing-dns v0.1.5-0.20230408004833-5adaf486d440
|
||||
github.com/sagernet/sing v0.2.3
|
||||
github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc
|
||||
github.com/sagernet/sing-shadowsocks v0.2.0
|
||||
github.com/sagernet/sing-shadowtls v0.1.0
|
||||
github.com/sagernet/sing-tun v0.1.4-0.20230326080954-8848c0e4cbab
|
||||
@@ -39,10 +40,9 @@ require (
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/stretchr/testify v1.8.2
|
||||
go.etcd.io/bbolt v1.3.7
|
||||
go.uber.org/atomic v1.10.0
|
||||
go.uber.org/zap v1.24.0
|
||||
go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35
|
||||
golang.org/x/crypto v0.7.0
|
||||
golang.org/x/crypto v0.8.0
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29
|
||||
golang.org/x/net v0.9.0
|
||||
golang.org/x/sys v0.7.0
|
||||
@@ -82,6 +82,7 @@ require (
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
golang.org/x/mod v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
|
||||
26
go.sum
26
go.sum
@@ -1,7 +1,7 @@
|
||||
berty.tech/go-libtor v1.0.385 h1:RWK94C3hZj6Z2GdvePpHJLnWYobFr3bY/OdUJ5aoEXw=
|
||||
berty.tech/go-libtor v1.0.385/go.mod h1:9swOOQVb+kmvuAlsgWUK/4c52pm69AdbJsxLzk+fJEw=
|
||||
github.com/Dreamacro/clash v1.14.0 h1:ehJ/C/1m9LEjmME72WSE/Y2YqbR3Q54AbjqiRCvtyW4=
|
||||
github.com/Dreamacro/clash v1.14.0/go.mod h1:ia2CU7V713H1QdCqMwOLK9U9V5Ay8X0voj3yQr2tk+I=
|
||||
github.com/Dreamacro/clash v1.15.0 h1:mlpD950VEggXZBNahV66hyKDRxcczkj3vymoAt78KyE=
|
||||
github.com/Dreamacro/clash v1.15.0/go.mod h1:WNH69bN11LiAdgdSr4hpkEuXVMfBbWyhEKMCTx9BtNE=
|
||||
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
@@ -35,6 +35,8 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8Wd
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
|
||||
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
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/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=
|
||||
@@ -51,8 +53,8 @@ github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbg
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20230327135226-74ae03f2425e h1:8ChxkWKTVYg7LKBvYNLNRnlobgbPrzzossZUoST2T7o=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20230327135226-74ae03f2425e/go.mod h1:IKrnDWs3/Mqq5n0lI+RxA2sB7MvN/vbMBP3ehXg65UI=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20230407062729-974c6f05fe16 h1:+aAGyK41KRn8jbF2Q7PLL0Sxwg6dShGcQSeCC7nZQ8E=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20230407062729-974c6f05fe16/go.mod h1:IKrnDWs3/Mqq5n0lI+RxA2sB7MvN/vbMBP3ehXg65UI=
|
||||
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
|
||||
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
@@ -101,8 +103,8 @@ github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 h1:KyhtFFt
|
||||
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0/go.mod h1:D4SFEOkJK+4W1v86ZhX0jPM0rAL498fyQAChqMtes/I=
|
||||
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA=
|
||||
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms=
|
||||
github.com/sagernet/gomobile v0.0.0-20221130124640-349ebaa752ca h1:w56+kf8BeqLqllrRJ1tdwKc3sCdWOn/DuNHpY9fAiqs=
|
||||
github.com/sagernet/gomobile v0.0.0-20221130124640-349ebaa752ca/go.mod h1:5YE39YkJkCcMsfq1jMKkjsrM2GfBoF9JVWnvU89hmvU=
|
||||
github.com/sagernet/gomobile v0.0.0-20230413023804-244d7ff07035 h1:KttYh6bBhIw8Y6/Ljn7CGwC3CKZn788rzMJmeAKjY+8=
|
||||
github.com/sagernet/gomobile v0.0.0-20230413023804-244d7ff07035/go.mod h1:5YE39YkJkCcMsfq1jMKkjsrM2GfBoF9JVWnvU89hmvU=
|
||||
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-20230202071646-a8c8afb18b32 h1:tztuJB+giOWNRKQEBVY2oI3PsheTooMdh+/yxemYQYY=
|
||||
@@ -111,10 +113,10 @@ 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.2-0.20230407053809-308e421e33c2 h1:VjeHDxEgpB2fqK5G16yBvtLacibvg3h2MsIjal0UXH0=
|
||||
github.com/sagernet/sing v0.2.2-0.20230407053809-308e421e33c2/go.mod h1:9uHswk2hITw8leDbiLS/xn0t9nzBcbePxzm9PJhwdlw=
|
||||
github.com/sagernet/sing-dns v0.1.5-0.20230408004833-5adaf486d440 h1:VH8/BcOVuApHtS+vKP+khxlGRcXH7KKhgkTDtNynqSQ=
|
||||
github.com/sagernet/sing-dns v0.1.5-0.20230408004833-5adaf486d440/go.mod h1:69PNSHyEmXdjf6C+bXBOdr2GQnPeEyWjIzo/MV8gmz8=
|
||||
github.com/sagernet/sing v0.2.3 h1:V50MvZ4c3Iij2lYFWPlzL1PyipwSzjGeN9x+Ox89vpk=
|
||||
github.com/sagernet/sing v0.2.3/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w=
|
||||
github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc h1:hmbuqKv48SAjiKPoqtJGvS5pEHVPZjTHq9CPwQY2cZ4=
|
||||
github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc/go.mod h1:ZKuuqgsHRxDahYrzgSgy4vIAGGuKPlIf4hLcNzYzLkY=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.0 h1:ILDWL7pwWfkPLEbviE/MyCgfjaBmJY/JVVY+5jhSb58=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.0/go.mod h1:ysYzszRLpNzJSorvlWRMuzU6Vchsp7sd52q+JNY4axw=
|
||||
github.com/sagernet/sing-shadowtls v0.1.0 h1:05MYce8aR5xfKIn+y7xRFsdKhKt44QZTSEQW+lG5IWQ=
|
||||
@@ -168,8 +170,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
|
||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
|
||||
@@ -10,11 +10,10 @@ import (
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/atomic"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
"go.uber.org/atomic"
|
||||
)
|
||||
|
||||
var _ adapter.Inbound = (*myInboundAdapter)(nil)
|
||||
|
||||
@@ -2,6 +2,7 @@ package ntp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
@@ -9,6 +10,7 @@ import (
|
||||
"github.com/sagernet/sing-box/common/settings"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing/common"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
@@ -20,7 +22,7 @@ var _ adapter.TimeService = (*Service)(nil)
|
||||
|
||||
type Service struct {
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
cancel common.ContextCancelCauseFunc
|
||||
server M.Socksaddr
|
||||
writeToSystem bool
|
||||
dialer N.Dialer
|
||||
@@ -30,7 +32,7 @@ type Service struct {
|
||||
}
|
||||
|
||||
func NewService(ctx context.Context, router adapter.Router, logger logger.Logger, options option.NTPOptions) *Service {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
ctx, cancel := common.ContextWithCancelCause(ctx)
|
||||
server := options.ServerOptions.Build()
|
||||
if server.Port == 0 {
|
||||
server.Port = 123
|
||||
@@ -64,7 +66,7 @@ func (s *Service) Start() error {
|
||||
|
||||
func (s *Service) Close() error {
|
||||
s.ticker.Stop()
|
||||
s.cancel()
|
||||
s.cancel(os.ErrClosed)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -102,11 +102,10 @@ func (d *DNS) handleConnection(ctx context.Context, conn net.Conn, metadata adap
|
||||
|
||||
func (d *DNS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
|
||||
ctx = adapter.WithContext(ctx, &metadata)
|
||||
fastClose, cancel := context.WithCancel(ctx)
|
||||
fastClose, cancel := common.ContextWithCancelCause(ctx)
|
||||
timeout := canceler.New(fastClose, cancel, C.DNSTimeout)
|
||||
var group task.Group
|
||||
group.Append0(func(ctx context.Context) error {
|
||||
defer cancel()
|
||||
_buffer := buf.StackNewSize(dns.FixedPacketSize)
|
||||
defer common.KeepAlive(_buffer)
|
||||
buffer := common.Dup(_buffer)
|
||||
@@ -115,11 +114,13 @@ func (d *DNS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metada
|
||||
buffer.FullReset()
|
||||
destination, err := conn.ReadPacket(buffer)
|
||||
if err != nil {
|
||||
cancel(err)
|
||||
return err
|
||||
}
|
||||
var message mDNS.Msg
|
||||
err = message.Unpack(buffer.Bytes())
|
||||
if err != nil {
|
||||
cancel(err)
|
||||
return err
|
||||
}
|
||||
timeout.Update()
|
||||
@@ -127,17 +128,22 @@ func (d *DNS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metada
|
||||
go func() error {
|
||||
response, err := d.router.Exchange(adapter.WithContext(ctx, &metadataInQuery), &message)
|
||||
if err != nil {
|
||||
cancel(err)
|
||||
return err
|
||||
}
|
||||
timeout.Update()
|
||||
responseBuffer := buf.NewPacket()
|
||||
n, err := response.PackBuffer(responseBuffer.FreeBytes())
|
||||
if err != nil {
|
||||
cancel(err)
|
||||
responseBuffer.Release()
|
||||
return err
|
||||
}
|
||||
responseBuffer.Truncate(len(n))
|
||||
err = conn.WritePacket(responseBuffer, destination)
|
||||
if err != nil {
|
||||
cancel(err)
|
||||
}
|
||||
return err
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -14,14 +14,14 @@ import (
|
||||
"github.com/sagernet/sing/common"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/protocol/http"
|
||||
sHTTP "github.com/sagernet/sing/protocol/http"
|
||||
)
|
||||
|
||||
var _ adapter.Outbound = (*HTTP)(nil)
|
||||
|
||||
type HTTP struct {
|
||||
myOutboundAdapter
|
||||
client *http.Client
|
||||
client *sHTTP.Client
|
||||
}
|
||||
|
||||
func NewHTTP(router adapter.Router, logger log.ContextLogger, tag string, options option.HTTPOutboundOptions) (*HTTP, error) {
|
||||
@@ -37,7 +37,12 @@ func NewHTTP(router adapter.Router, logger log.ContextLogger, tag string, option
|
||||
logger: logger,
|
||||
tag: tag,
|
||||
},
|
||||
http.NewClient(detour, options.ServerOptions.Build(), options.Username, options.Password, nil),
|
||||
sHTTP.NewClient(sHTTP.Options{
|
||||
Dialer: detour,
|
||||
Server: options.ServerOptions.Build(),
|
||||
Username: options.Username,
|
||||
Password: options.Password,
|
||||
}),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ func (h *shadowsocksDialer) DialContext(ctx context.Context, network string, des
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &bufio.BindPacketConn{PacketConn: h.method.DialPacketConn(outConn), Addr: destination}, nil
|
||||
return bufio.NewBindPacketConn(h.method.DialPacketConn(outConn), destination), nil
|
||||
default:
|
||||
return nil, E.Extend(N.ErrUnknownNetwork, network)
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ func (h *trojanDialer) DialContext(ctx context.Context, network string, destinat
|
||||
case N.NetworkTCP:
|
||||
return trojan.NewClientConn(conn, h.key, destination), nil
|
||||
case N.NetworkUDP:
|
||||
return &bufio.BindPacketConn{PacketConn: trojan.NewClientPacketConn(conn, h.key), Addr: destination}, nil
|
||||
return bufio.NewBindPacketConn(trojan.NewClientPacketConn(conn, h.key), destination), nil
|
||||
default:
|
||||
return nil, E.Extend(N.ErrUnknownNetwork, network)
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ func (h *VLESS) DialContext(ctx context.Context, network string, destination M.S
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &bufio.BindPacketConn{PacketConn: packetaddr.NewConn(packetConn, destination), Addr: destination}, nil
|
||||
return bufio.NewBindPacketConn(packetaddr.NewConn(packetConn, destination), destination), nil
|
||||
} else {
|
||||
return h.client.DialEarlyPacketConn(conn, destination)
|
||||
}
|
||||
|
||||
@@ -631,7 +631,7 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
|
||||
if metadata.InboundOptions.SniffEnabled {
|
||||
buffer := buf.NewPacket()
|
||||
buffer.FullReset()
|
||||
sniffMetadata, _ := sniff.PeekStream(ctx, conn, buffer, time.Duration(metadata.InboundOptions.SniffTimeout), sniff.StreamDomainNameQuery, sniff.TLSClientHello, sniff.HTTPHost)
|
||||
sniffMetadata, err := sniff.PeekStream(ctx, conn, buffer, time.Duration(metadata.InboundOptions.SniffTimeout), sniff.StreamDomainNameQuery, sniff.TLSClientHello, sniff.HTTPHost)
|
||||
if sniffMetadata != nil {
|
||||
metadata.Protocol = sniffMetadata.Protocol
|
||||
metadata.Domain = sniffMetadata.Domain
|
||||
@@ -646,6 +646,8 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
|
||||
} else {
|
||||
r.logger.DebugContext(ctx, "sniffed protocol: ", metadata.Protocol)
|
||||
}
|
||||
} else if err != nil {
|
||||
r.logger.TraceContext(ctx, "sniffed no protocol: ", err)
|
||||
}
|
||||
if !buffer.IsEmpty() {
|
||||
conn = bufio.NewCachedConn(conn, buffer)
|
||||
|
||||
@@ -498,7 +498,12 @@ func (c *PacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
return
|
||||
}
|
||||
n = copy(p, msg.Data)
|
||||
addr = M.ParseSocksaddrHostPort(msg.Host, msg.Port).UDPAddr()
|
||||
destination := M.ParseSocksaddrHostPort(msg.Host, msg.Port)
|
||||
if destination.IsFqdn() {
|
||||
addr = destination
|
||||
} else {
|
||||
addr = destination.UDPAddr()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -32,10 +32,10 @@ type TLSObfs struct {
|
||||
func (to *TLSObfs) read(b []byte, discardN int) (int, error) {
|
||||
buf := B.Get(discardN)
|
||||
_, err := io.ReadFull(to.Conn, buf)
|
||||
B.Put(buf)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
B.Put(buf)
|
||||
|
||||
sizeBuf := make([]byte, 2)
|
||||
_, err = io.ReadFull(to.Conn, sizeBuf)
|
||||
|
||||
@@ -131,7 +131,11 @@ func (c *ClientPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)
|
||||
return
|
||||
}
|
||||
n = buffer.Len()
|
||||
addr = destination.UDPAddr()
|
||||
if destination.IsFqdn() {
|
||||
addr = destination
|
||||
} else {
|
||||
addr = destination.UDPAddr()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ func NewClientTransport(ctx context.Context, dialer N.Dialer, serverAddr M.Socks
|
||||
}
|
||||
switch options.Type {
|
||||
case C.V2RayTransportTypeHTTP:
|
||||
return v2rayhttp.NewClient(ctx, dialer, serverAddr, options.HTTPOptions, tlsConfig), nil
|
||||
return v2rayhttp.NewClient(ctx, dialer, serverAddr, options.HTTPOptions, tlsConfig)
|
||||
case C.V2RayTransportTypeGRPC:
|
||||
if tlsConfig == nil {
|
||||
return nil, C.ErrTLSRequired
|
||||
|
||||
@@ -101,10 +101,10 @@ func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
||||
return nil, err
|
||||
}
|
||||
client := NewGunServiceClient(clientConn).(GunServiceCustomNameClient)
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
ctx, cancel := common.ContextWithCancelCause(ctx)
|
||||
stream, err := client.TunCustomName(ctx, c.serviceName)
|
||||
if err != nil {
|
||||
cancel()
|
||||
cancel(err)
|
||||
return nil, err
|
||||
}
|
||||
return NewGRPCConn(stream, cancel), nil
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package v2raygrpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/common/baderror"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/rw"
|
||||
)
|
||||
|
||||
@@ -14,11 +14,11 @@ var _ net.Conn = (*GRPCConn)(nil)
|
||||
|
||||
type GRPCConn struct {
|
||||
GunService
|
||||
cancel context.CancelFunc
|
||||
cancel common.ContextCancelCauseFunc
|
||||
cache []byte
|
||||
}
|
||||
|
||||
func NewGRPCConn(service GunService, cancel context.CancelFunc) *GRPCConn {
|
||||
func NewGRPCConn(service GunService, cancel common.ContextCancelCauseFunc) *GRPCConn {
|
||||
if client, isClient := service.(GunService_TunClient); isClient {
|
||||
service = &clientConnWrapper{client}
|
||||
}
|
||||
@@ -37,6 +37,7 @@ func (c *GRPCConn) Read(b []byte) (n int, err error) {
|
||||
hunk, err := c.Recv()
|
||||
err = baderror.WrapGRPC(err)
|
||||
if err != nil {
|
||||
c.cancel(err)
|
||||
return
|
||||
}
|
||||
n = copy(b, hunk.Data)
|
||||
@@ -49,13 +50,14 @@ func (c *GRPCConn) Read(b []byte) (n int, err error) {
|
||||
func (c *GRPCConn) Write(b []byte) (n int, err error) {
|
||||
err = baderror.WrapGRPC(c.Send(&Hunk{Data: b}))
|
||||
if err != nil {
|
||||
c.cancel(err)
|
||||
return
|
||||
}
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (c *GRPCConn) Close() error {
|
||||
c.cancel()
|
||||
c.cancel(net.ErrClosed)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,11 @@ import (
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/tls"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing/common"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
"golang.org/x/net/http2"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/keepalive"
|
||||
gM "google.golang.org/grpc/metadata"
|
||||
@@ -30,7 +32,9 @@ type Server struct {
|
||||
func NewServer(ctx context.Context, options option.V2RayGRPCOptions, tlsConfig tls.ServerConfig, handler N.TCPConnectionHandler) (*Server, error) {
|
||||
var serverOptions []grpc.ServerOption
|
||||
if tlsConfig != nil {
|
||||
tlsConfig.SetNextProtos([]string{"h2"})
|
||||
if !common.Contains(tlsConfig.NextProtos(), http2.NextProtoTLS) {
|
||||
tlsConfig.SetNextProtos(append([]string{"h2"}, tlsConfig.NextProtos()...))
|
||||
}
|
||||
serverOptions = append(serverOptions, grpc.Creds(NewTLSTransportCredentials(tlsConfig)))
|
||||
}
|
||||
if options.IdleTimeout > 0 {
|
||||
@@ -45,7 +49,7 @@ func NewServer(ctx context.Context, options option.V2RayGRPCOptions, tlsConfig t
|
||||
}
|
||||
|
||||
func (s *Server) Tun(server GunService_TunServer) error {
|
||||
ctx, cancel := context.WithCancel(s.ctx)
|
||||
ctx, cancel := common.ContextWithCancelCause(s.ctx)
|
||||
conn := NewGRPCConn(server, cancel)
|
||||
var metadata M.Metadata
|
||||
if remotePeer, loaded := peer.FromContext(server.Context()); loaded {
|
||||
|
||||
@@ -92,14 +92,16 @@ func (s *Server) fallbackRequest(ctx context.Context, writer http.ResponseWriter
|
||||
} else if fErr == os.ErrInvalid {
|
||||
fErr = nil
|
||||
}
|
||||
writer.WriteHeader(statusCode)
|
||||
if statusCode > 0 {
|
||||
writer.WriteHeader(statusCode)
|
||||
}
|
||||
s.handler.NewError(request.Context(), E.Cause(E.Errors(err, E.Cause(fErr, "fallback connection")), "process connection from ", request.RemoteAddr))
|
||||
}
|
||||
|
||||
func (s *Server) Serve(listener net.Listener) error {
|
||||
if s.tlsConfig != nil {
|
||||
if len(s.tlsConfig.NextProtos()) == 0 {
|
||||
s.tlsConfig.SetNextProtos([]string{http2.NextProtoTLS})
|
||||
if !common.Contains(s.tlsConfig.NextProtos(), http2.NextProtoTLS) {
|
||||
s.tlsConfig.SetNextProtos(append([]string{"h2"}, s.tlsConfig.NextProtos()...))
|
||||
}
|
||||
listener = aTLS.NewListener(listener, s.tlsConfig)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
@@ -16,6 +15,7 @@ import (
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
sHTTP "github.com/sagernet/sing/protocol/http"
|
||||
|
||||
"golang.org/x/net/http2"
|
||||
)
|
||||
@@ -34,7 +34,7 @@ type Client struct {
|
||||
headers http.Header
|
||||
}
|
||||
|
||||
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayHTTPOptions, tlsConfig tls.Config) adapter.V2RayClientTransport {
|
||||
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayHTTPOptions, tlsConfig tls.Config) (adapter.V2RayClientTransport, error) {
|
||||
var transport http.RoundTripper
|
||||
if tlsConfig == nil {
|
||||
transport = &http.Transport{
|
||||
@@ -77,14 +77,15 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
|
||||
}
|
||||
uri.Host = serverAddr.String()
|
||||
uri.Path = options.Path
|
||||
if !strings.HasPrefix(uri.Path, "/") {
|
||||
uri.Path = "/" + uri.Path
|
||||
err := sHTTP.URLSetPath(&uri, options.Path)
|
||||
if err != nil {
|
||||
return nil, E.New("failed to set path: " + err.Error())
|
||||
}
|
||||
for key, valueList := range options.Headers {
|
||||
client.headers[key] = valueList
|
||||
}
|
||||
client.url = &uri
|
||||
return client
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
||||
|
||||
@@ -102,28 +102,40 @@ func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
writer.WriteHeader(http.StatusOK)
|
||||
writer.(http.Flusher).Flush()
|
||||
|
||||
var metadata M.Metadata
|
||||
metadata.Source = sHttp.SourceAddress(request)
|
||||
if h, ok := writer.(http.Hijacker); ok {
|
||||
var requestBody *buf.Buffer
|
||||
if contentLength := int(request.ContentLength); contentLength > 0 {
|
||||
requestBody = buf.NewSize(contentLength)
|
||||
_, err := requestBody.ReadFullFrom(request.Body, contentLength)
|
||||
if err != nil {
|
||||
s.fallbackRequest(request.Context(), writer, request, 0, E.Cause(err, "read request"))
|
||||
return
|
||||
}
|
||||
}
|
||||
writer.WriteHeader(http.StatusOK)
|
||||
writer.(http.Flusher).Flush()
|
||||
conn, reader, err := h.Hijack()
|
||||
if err != nil {
|
||||
s.fallbackRequest(request.Context(), writer, request, http.StatusInternalServerError, E.Cause(err, "hijack conn"))
|
||||
s.fallbackRequest(request.Context(), writer, request, 0, E.Cause(err, "hijack conn"))
|
||||
return
|
||||
}
|
||||
if cacheLen := reader.Reader.Buffered(); cacheLen > 0 {
|
||||
cache := buf.NewSize(cacheLen)
|
||||
_, err = cache.ReadFullFrom(reader.Reader, cacheLen)
|
||||
if err != nil {
|
||||
s.fallbackRequest(request.Context(), writer, request, http.StatusInternalServerError, E.Cause(err, "read cache"))
|
||||
s.fallbackRequest(request.Context(), writer, request, 0, E.Cause(err, "read cache"))
|
||||
return
|
||||
}
|
||||
conn = bufio.NewCachedConn(conn, cache)
|
||||
}
|
||||
if requestBody != nil {
|
||||
conn = bufio.NewCachedConn(conn, requestBody)
|
||||
}
|
||||
s.handler.NewConnection(request.Context(), conn, metadata)
|
||||
} else {
|
||||
writer.WriteHeader(http.StatusOK)
|
||||
conn := NewHTTP2Wrapper(&ServerHTTPConn{
|
||||
NewHTTPConn(request.Body, writer),
|
||||
writer.(http.Flusher),
|
||||
@@ -141,12 +153,19 @@ func (s *Server) fallbackRequest(ctx context.Context, writer http.ResponseWriter
|
||||
} else if fErr == os.ErrInvalid {
|
||||
fErr = nil
|
||||
}
|
||||
writer.WriteHeader(statusCode)
|
||||
if statusCode > 0 {
|
||||
writer.WriteHeader(statusCode)
|
||||
}
|
||||
s.handler.NewError(request.Context(), E.Cause(E.Errors(err, E.Cause(fErr, "fallback connection")), "process connection from ", request.RemoteAddr))
|
||||
}
|
||||
|
||||
func (s *Server) Serve(listener net.Listener) error {
|
||||
if s.tlsConfig != nil {
|
||||
if len(s.tlsConfig.NextProtos()) == 0 {
|
||||
s.tlsConfig.SetNextProtos([]string{http2.NextProtoTLS, "http/1.1"})
|
||||
} else if !common.Contains(s.tlsConfig.NextProtos(), http2.NextProtoTLS) {
|
||||
s.tlsConfig.SetNextProtos(append([]string{"h2"}, s.tlsConfig.NextProtos()...))
|
||||
}
|
||||
listener = aTLS.NewListener(listener, s.tlsConfig)
|
||||
}
|
||||
return s.httpServer.Serve(listener)
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
@@ -14,6 +13,7 @@ import (
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
sHTTP "github.com/sagernet/sing/protocol/http"
|
||||
"github.com/sagernet/websocket"
|
||||
)
|
||||
|
||||
@@ -57,8 +57,9 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
|
||||
}
|
||||
uri.Host = serverAddr.String()
|
||||
uri.Path = options.Path
|
||||
if !strings.HasPrefix(uri.Path, "/") {
|
||||
uri.Path = "/" + uri.Path
|
||||
err := sHTTP.URLSetPath(&uri, options.Path)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
headers := make(http.Header)
|
||||
for key, value := range options.Headers {
|
||||
|
||||
@@ -69,6 +69,14 @@ func (c *WebsocketConn) SetDeadline(t time.Time) error {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
|
||||
func (c *WebsocketConn) SetReadDeadline(t time.Time) error {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
|
||||
func (c *WebsocketConn) SetWriteDeadline(t time.Time) error {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
|
||||
func (c *WebsocketConn) Upstream() any {
|
||||
return c.Conn.NetConn()
|
||||
}
|
||||
@@ -195,24 +203,15 @@ func (c *EarlyWebsocketConn) RemoteAddr() net.Addr {
|
||||
}
|
||||
|
||||
func (c *EarlyWebsocketConn) SetDeadline(t time.Time) error {
|
||||
if c.conn == nil {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
return c.conn.SetDeadline(t)
|
||||
return os.ErrInvalid
|
||||
}
|
||||
|
||||
func (c *EarlyWebsocketConn) SetReadDeadline(t time.Time) error {
|
||||
if c.conn == nil {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
return c.conn.SetReadDeadline(t)
|
||||
return os.ErrInvalid
|
||||
}
|
||||
|
||||
func (c *EarlyWebsocketConn) SetWriteDeadline(t time.Time) error {
|
||||
if c.conn == nil {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
return c.conn.SetWriteDeadline(t)
|
||||
return os.ErrInvalid
|
||||
}
|
||||
|
||||
func (c *EarlyWebsocketConn) Upstream() any {
|
||||
|
||||
@@ -95,7 +95,7 @@ func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
wsConn, err := upgrader.Upgrade(writer, request, nil)
|
||||
if err != nil {
|
||||
s.fallbackRequest(request.Context(), writer, request, http.StatusBadRequest, E.Cause(err, "upgrade websocket connection"))
|
||||
s.fallbackRequest(request.Context(), writer, request, 0, E.Cause(err, "upgrade websocket connection"))
|
||||
return
|
||||
}
|
||||
var metadata M.Metadata
|
||||
@@ -115,7 +115,9 @@ func (s *Server) fallbackRequest(ctx context.Context, writer http.ResponseWriter
|
||||
} else if fErr == os.ErrInvalid {
|
||||
fErr = nil
|
||||
}
|
||||
writer.WriteHeader(statusCode)
|
||||
if statusCode > 0 {
|
||||
writer.WriteHeader(statusCode)
|
||||
}
|
||||
s.handler.NewError(request.Context(), E.Cause(E.Errors(err, E.Cause(fErr, "fallback connection")), "process connection from ", request.RemoteAddr))
|
||||
}
|
||||
|
||||
|
||||
@@ -196,7 +196,11 @@ func (c *PacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
addr = c.destination.UDPAddr()
|
||||
if c.destination.IsFqdn() {
|
||||
addr = c.destination
|
||||
} else {
|
||||
addr = c.destination.UDPAddr()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -146,7 +146,11 @@ func (c *serverPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
addr = c.destination.UDPAddr()
|
||||
if c.destination.IsFqdn() {
|
||||
addr = c.destination
|
||||
} else {
|
||||
addr = c.destination.UDPAddr()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user