mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-04-13 20:28:32 +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
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: ${{ steps.version.outputs.go_version }}
|
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
|
- name: Add cache to Go proxy
|
||||||
run: |
|
run: |
|
||||||
version=`git rev-parse HEAD`
|
version=`git rev-parse HEAD`
|
||||||
@@ -196,12 +190,6 @@ jobs:
|
|||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: ${{ steps.version.outputs.go_version }}
|
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
|
- name: Build
|
||||||
id: build
|
id: build
|
||||||
run: make
|
run: make
|
||||||
|
|||||||
6
.github/workflows/lint.yml
vendored
6
.github/workflows/lint.yml
vendored
@@ -31,12 +31,6 @@ jobs:
|
|||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: ${{ steps.version.outputs.go_version }}
|
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
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v3
|
uses: golangci/golangci-lint-action@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
13
Makefile
13
Makefile
@@ -77,13 +77,20 @@ test_stdio:
|
|||||||
go mod tidy && \
|
go mod tidy && \
|
||||||
go test -v -tags "$(TAGS_TEST),force_stdio" .
|
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:
|
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:
|
lib_install:
|
||||||
go get -v -d
|
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/gomobile@v0.0.0-20230413023804-244d7ff07035
|
||||||
go install -v github.com/sagernet/gomobile/cmd/gobind@v0.0.0-20221130124640-349ebaa752ca
|
go install -v github.com/sagernet/gomobile/cmd/gobind@v0.0.0-20230413023804-244d7ff07035
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf bin dist sing-box
|
rm -rf bin dist sing-box
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ The universal proxy platform.
|
|||||||
|
|
||||||
https://sing-box.sagernet.org
|
https://sing-box.sagernet.org
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
https://community.sagernet.org/c/sing-box/
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ type Conn struct {
|
|||||||
element *list.Element[io.Closer]
|
element *list.Element[io.Closer]
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConn(conn net.Conn) (*Conn, error) {
|
func NewConn(conn net.Conn) (net.Conn, error) {
|
||||||
connAccess.Lock()
|
connAccess.Lock()
|
||||||
element := openConnection.PushBack(conn)
|
element := openConnection.PushBack(conn)
|
||||||
connAccess.Unlock()
|
connAccess.Unlock()
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ type PacketConn struct {
|
|||||||
element *list.Element[io.Closer]
|
element *list.Element[io.Closer]
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPacketConn(conn net.PacketConn) (*PacketConn, error) {
|
func NewPacketConn(conn net.PacketConn) (net.PacketConn, error) {
|
||||||
connAccess.Lock()
|
connAccess.Lock()
|
||||||
element := openConnection.PushBack(conn)
|
element := openConnection.PushBack(conn)
|
||||||
connAccess.Unlock()
|
connAccess.Unlock()
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ func (d *ResolveDialer) ListenPacket(ctx context.Context, destination M.Socksadd
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
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 {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addr = destination.UDPAddr()
|
if destination.IsFqdn() {
|
||||||
|
addr = destination
|
||||||
|
} else {
|
||||||
|
addr = destination.UDPAddr()
|
||||||
|
}
|
||||||
var length uint16
|
var length uint16
|
||||||
err = binary.Read(c.ExtendedConn, binary.BigEndian, &length)
|
err = binary.Read(c.ExtendedConn, binary.BigEndian, &length)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ package process
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"os/user"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
"github.com/sagernet/sing-tun"
|
"github.com/sagernet/sing-tun"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
F "github.com/sagernet/sing/common/format"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Searcher interface {
|
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) {
|
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))
|
err := conn.SetReadDeadline(time.Now().Add(timeout))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, E.Cause(err, "set read deadline")
|
||||||
}
|
}
|
||||||
_, err = buffer.ReadOnceFrom(conn)
|
_, err = buffer.ReadOnceFrom(conn)
|
||||||
err = E.Errors(err, conn.SetReadDeadline(time.Time{}))
|
err = E.Errors(err, conn.SetReadDeadline(time.Time{}))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, E.Cause(err, "read payload")
|
||||||
}
|
}
|
||||||
var metadata *adapter.InboundContext
|
var metadata *adapter.InboundContext
|
||||||
var errors []error
|
var errors []error
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ func NewSTDServer(ctx context.Context, router adapter.Router, logger log.Logger,
|
|||||||
tlsConfig.ServerName = options.ServerName
|
tlsConfig.ServerName = options.ServerName
|
||||||
}
|
}
|
||||||
if len(options.ALPN) > 0 {
|
if len(options.ALPN) > 0 {
|
||||||
tlsConfig.NextProtos = append(tlsConfig.NextProtos, options.ALPN...)
|
tlsConfig.NextProtos = append(options.ALPN, tlsConfig.NextProtos...)
|
||||||
}
|
}
|
||||||
if options.MinVersion != "" {
|
if options.MinVersion != "" {
|
||||||
minVersion, err := ParseTLSVersion(options.MinVersion)
|
minVersion, err := ParseTLSVersion(options.MinVersion)
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
#### 1.2.4
|
||||||
|
|
||||||
|
* Fixes and improvements
|
||||||
|
|
||||||
#### 1.2.3
|
#### 1.2.3
|
||||||
|
|
||||||
* Introducing our [new Android client application](/installation/clients/sfa)
|
* Introducing our [new Android client application](/installation/clients/sfa)
|
||||||
|
|||||||
@@ -4,32 +4,26 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/experimental/clashapi/compatible"
|
"github.com/sagernet/sing-box/experimental/clashapi/compatible"
|
||||||
|
"github.com/sagernet/sing/common/atomic"
|
||||||
"go.uber.org/atomic"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
connections compatible.Map[string, tracker]
|
uploadTemp atomic.Int64
|
||||||
uploadTemp *atomic.Int64
|
downloadTemp atomic.Int64
|
||||||
downloadTemp *atomic.Int64
|
uploadBlip atomic.Int64
|
||||||
uploadBlip *atomic.Int64
|
downloadBlip atomic.Int64
|
||||||
downloadBlip *atomic.Int64
|
uploadTotal atomic.Int64
|
||||||
uploadTotal *atomic.Int64
|
downloadTotal atomic.Int64
|
||||||
downloadTotal *atomic.Int64
|
|
||||||
ticker *time.Ticker
|
connections compatible.Map[string, tracker]
|
||||||
done chan struct{}
|
ticker *time.Ticker
|
||||||
|
done chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewManager() *Manager {
|
func NewManager() *Manager {
|
||||||
manager := &Manager{
|
manager := &Manager{
|
||||||
uploadTemp: atomic.NewInt64(0),
|
ticker: time.NewTicker(time.Second),
|
||||||
downloadTemp: atomic.NewInt64(0),
|
done: make(chan struct{}),
|
||||||
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{}),
|
|
||||||
}
|
}
|
||||||
go manager.handle()
|
go manager.handle()
|
||||||
return manager
|
return manager
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package trafficontrol
|
package trafficontrol
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"time"
|
"time"
|
||||||
@@ -8,10 +9,10 @@ import (
|
|||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
"github.com/sagernet/sing-box/experimental/trackerconn"
|
"github.com/sagernet/sing-box/experimental/trackerconn"
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/atomic"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid/v5"
|
||||||
"go.uber.org/atomic"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Metadata struct {
|
type Metadata struct {
|
||||||
@@ -43,6 +44,19 @@ type trackerInfo struct {
|
|||||||
RulePayload string `json:"rulePayload"`
|
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 {
|
type tcpTracker struct {
|
||||||
N.ExtendedConn `json:"-"`
|
N.ExtendedConn `json:"-"`
|
||||||
*trackerInfo
|
*trackerInfo
|
||||||
@@ -97,8 +111,8 @@ func NewTCPTracker(conn net.Conn, manager *Manager, metadata Metadata, router ad
|
|||||||
next = group.Now()
|
next = group.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
upload := atomic.NewInt64(0)
|
upload := new(atomic.Int64)
|
||||||
download := atomic.NewInt64(0)
|
download := new(atomic.Int64)
|
||||||
|
|
||||||
t := &tcpTracker{
|
t := &tcpTracker{
|
||||||
ExtendedConn: trackerconn.NewHook(conn, func(n int64) {
|
ExtendedConn: trackerconn.NewHook(conn, func(n int64) {
|
||||||
@@ -184,8 +198,8 @@ func NewUDPTracker(conn N.PacketConn, manager *Manager, metadata Metadata, route
|
|||||||
next = group.Now()
|
next = group.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
upload := atomic.NewInt64(0)
|
upload := new(atomic.Int64)
|
||||||
download := atomic.NewInt64(0)
|
download := new(atomic.Int64)
|
||||||
|
|
||||||
ut := &udpTracker{
|
ut := &udpTracker{
|
||||||
PacketConn: trackerconn.NewHookPacket(conn, func(n int64) {
|
PacketConn: trackerconn.NewHookPacket(conn, func(n int64) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/debug"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
"github.com/sagernet/sing/common/observable"
|
"github.com/sagernet/sing/common/observable"
|
||||||
"github.com/sagernet/sing/common/x/list"
|
"github.com/sagernet/sing/common/x/list"
|
||||||
@@ -71,7 +72,9 @@ func (s *CommandServer) loopConnection(listener net.Listener) {
|
|||||||
go func() {
|
go func() {
|
||||||
hErr := s.handleConnection(conn)
|
hErr := s.handleConnection(conn)
|
||||||
if hErr != nil && !E.IsClosed(err) {
|
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 {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return nil
|
return ctx.Err()
|
||||||
case <-ticker.C:
|
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 (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing/common/atomic"
|
||||||
"github.com/sagernet/sing/common/buf"
|
"github.com/sagernet/sing/common/buf"
|
||||||
"github.com/sagernet/sing/common/bufio"
|
"github.com/sagernet/sing/common/bufio"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
|
||||||
"go.uber.org/atomic"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(conn net.Conn, readCounter []*atomic.Int64, writeCounter []*atomic.Int64) *Conn {
|
func New(conn net.Conn, readCounter []*atomic.Int64, writeCounter []*atomic.Int64) *Conn {
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
package trackerconn
|
package trackerconn
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/sagernet/sing/common/atomic"
|
||||||
"github.com/sagernet/sing/common/buf"
|
"github.com/sagernet/sing/common/buf"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
|
||||||
"go.uber.org/atomic"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewPacket(conn N.PacketConn, readCounter []*atomic.Int64, writeCounter []*atomic.Int64) *PacketConn {
|
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/adapter"
|
||||||
"github.com/sagernet/sing-box/experimental/trackerconn"
|
"github.com/sagernet/sing-box/experimental/trackerconn"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing/common/atomic"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
|
||||||
"go.uber.org/atomic"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -211,7 +210,7 @@ func (s *StatsService) loadOrCreateCounter(name string) *atomic.Int64 {
|
|||||||
if loaded {
|
if loaded {
|
||||||
return counter
|
return counter
|
||||||
}
|
}
|
||||||
counter = atomic.NewInt64(0)
|
counter = &atomic.Int64{}
|
||||||
s.counters[name] = counter
|
s.counters[name] = counter
|
||||||
return counter
|
return counter
|
||||||
}
|
}
|
||||||
|
|||||||
15
go.mod
15
go.mod
@@ -4,7 +4,7 @@ go 1.18
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
berty.tech/go-libtor v1.0.385
|
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/caddyserver/certmagic v0.17.2
|
||||||
github.com/cretz/bine v0.2.0
|
github.com/cretz/bine v0.2.0
|
||||||
github.com/dustin/go-humanize v1.0.1
|
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/cors v1.2.1
|
||||||
github.com/go-chi/render v1.0.2
|
github.com/go-chi/render v1.0.2
|
||||||
github.com/gofrs/uuid v4.4.0+incompatible
|
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/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/logrusorgru/aurora v2.0.3+incompatible
|
||||||
github.com/mholt/acmez v1.1.0
|
github.com/mholt/acmez v1.1.0
|
||||||
github.com/miekg/dns v1.1.53
|
github.com/miekg/dns v1.1.53
|
||||||
@@ -22,11 +23,11 @@ require (
|
|||||||
github.com/oschwald/maxminddb-golang v1.10.0
|
github.com/oschwald/maxminddb-golang v1.10.0
|
||||||
github.com/pires/go-proxyproto v0.7.0
|
github.com/pires/go-proxyproto v0.7.0
|
||||||
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0
|
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/quic-go v0.0.0-20230202071646-a8c8afb18b32
|
||||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
|
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
|
||||||
github.com/sagernet/sing v0.2.2-0.20230407053809-308e421e33c2
|
github.com/sagernet/sing v0.2.3
|
||||||
github.com/sagernet/sing-dns v0.1.5-0.20230408004833-5adaf486d440
|
github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc
|
||||||
github.com/sagernet/sing-shadowsocks v0.2.0
|
github.com/sagernet/sing-shadowsocks v0.2.0
|
||||||
github.com/sagernet/sing-shadowtls v0.1.0
|
github.com/sagernet/sing-shadowtls v0.1.0
|
||||||
github.com/sagernet/sing-tun v0.1.4-0.20230326080954-8848c0e4cbab
|
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/spf13/cobra v1.7.0
|
||||||
github.com/stretchr/testify v1.8.2
|
github.com/stretchr/testify v1.8.2
|
||||||
go.etcd.io/bbolt v1.3.7
|
go.etcd.io/bbolt v1.3.7
|
||||||
go.uber.org/atomic v1.10.0
|
|
||||||
go.uber.org/zap v1.24.0
|
go.uber.org/zap v1.24.0
|
||||||
go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35
|
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/exp v0.0.0-20230321023759-10a507213a29
|
||||||
golang.org/x/net v0.9.0
|
golang.org/x/net v0.9.0
|
||||||
golang.org/x/sys v0.7.0
|
golang.org/x/sys v0.7.0
|
||||||
@@ -82,6 +82,7 @@ require (
|
|||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect
|
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect
|
||||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // 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
|
go.uber.org/multierr v1.6.0 // indirect
|
||||||
golang.org/x/mod v0.8.0 // indirect
|
golang.org/x/mod v0.8.0 // indirect
|
||||||
golang.org/x/text v0.9.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 h1:RWK94C3hZj6Z2GdvePpHJLnWYobFr3bY/OdUJ5aoEXw=
|
||||||
berty.tech/go-libtor v1.0.385/go.mod h1:9swOOQVb+kmvuAlsgWUK/4c52pm69AdbJsxLzk+fJEw=
|
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.15.0 h1:mlpD950VEggXZBNahV66hyKDRxcczkj3vymoAt78KyE=
|
||||||
github.com/Dreamacro/clash v1.14.0/go.mod h1:ia2CU7V713H1QdCqMwOLK9U9V5Ay8X0voj3yQr2tk+I=
|
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 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
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/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 h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
|
||||||
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
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 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.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/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 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
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-20230407062729-974c6f05fe16 h1:+aAGyK41KRn8jbF2Q7PLL0Sxwg6dShGcQSeCC7nZQ8E=
|
||||||
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/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.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 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
|
||||||
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
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/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 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA=
|
||||||
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms=
|
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-20230413023804-244d7ff07035 h1:KttYh6bBhIw8Y6/Ljn7CGwC3CKZn788rzMJmeAKjY+8=
|
||||||
github.com/sagernet/gomobile v0.0.0-20221130124640-349ebaa752ca/go.mod h1:5YE39YkJkCcMsfq1jMKkjsrM2GfBoF9JVWnvU89hmvU=
|
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 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-20230202071646-a8c8afb18b32 h1:tztuJB+giOWNRKQEBVY2oI3PsheTooMdh+/yxemYQYY=
|
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/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.2-0.20230407053809-308e421e33c2 h1:VjeHDxEgpB2fqK5G16yBvtLacibvg3h2MsIjal0UXH0=
|
github.com/sagernet/sing v0.2.3 h1:V50MvZ4c3Iij2lYFWPlzL1PyipwSzjGeN9x+Ox89vpk=
|
||||||
github.com/sagernet/sing v0.2.2-0.20230407053809-308e421e33c2/go.mod h1:9uHswk2hITw8leDbiLS/xn0t9nzBcbePxzm9PJhwdlw=
|
github.com/sagernet/sing v0.2.3/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w=
|
||||||
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.20230415085626-111ecf799dfc h1:hmbuqKv48SAjiKPoqtJGvS5pEHVPZjTHq9CPwQY2cZ4=
|
||||||
github.com/sagernet/sing-dns v0.1.5-0.20230408004833-5adaf486d440/go.mod h1:69PNSHyEmXdjf6C+bXBOdr2GQnPeEyWjIzo/MV8gmz8=
|
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 h1:ILDWL7pwWfkPLEbviE/MyCgfjaBmJY/JVVY+5jhSb58=
|
||||||
github.com/sagernet/sing-shadowsocks v0.2.0/go.mod h1:ysYzszRLpNzJSorvlWRMuzU6Vchsp7sd52q+JNY4axw=
|
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=
|
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-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-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.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
|
||||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
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 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
|
||||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
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=
|
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/log"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
|
"github.com/sagernet/sing/common/atomic"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
|
||||||
"go.uber.org/atomic"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ adapter.Inbound = (*myInboundAdapter)(nil)
|
var _ adapter.Inbound = (*myInboundAdapter)(nil)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package ntp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
@@ -9,6 +10,7 @@ import (
|
|||||||
"github.com/sagernet/sing-box/common/settings"
|
"github.com/sagernet/sing-box/common/settings"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
"github.com/sagernet/sing/common/logger"
|
"github.com/sagernet/sing/common/logger"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
@@ -20,7 +22,7 @@ var _ adapter.TimeService = (*Service)(nil)
|
|||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel common.ContextCancelCauseFunc
|
||||||
server M.Socksaddr
|
server M.Socksaddr
|
||||||
writeToSystem bool
|
writeToSystem bool
|
||||||
dialer N.Dialer
|
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 {
|
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()
|
server := options.ServerOptions.Build()
|
||||||
if server.Port == 0 {
|
if server.Port == 0 {
|
||||||
server.Port = 123
|
server.Port = 123
|
||||||
@@ -64,7 +66,7 @@ func (s *Service) Start() error {
|
|||||||
|
|
||||||
func (s *Service) Close() error {
|
func (s *Service) Close() error {
|
||||||
s.ticker.Stop()
|
s.ticker.Stop()
|
||||||
s.cancel()
|
s.cancel(os.ErrClosed)
|
||||||
return nil
|
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 {
|
func (d *DNS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
|
||||||
ctx = adapter.WithContext(ctx, &metadata)
|
ctx = adapter.WithContext(ctx, &metadata)
|
||||||
fastClose, cancel := context.WithCancel(ctx)
|
fastClose, cancel := common.ContextWithCancelCause(ctx)
|
||||||
timeout := canceler.New(fastClose, cancel, C.DNSTimeout)
|
timeout := canceler.New(fastClose, cancel, C.DNSTimeout)
|
||||||
var group task.Group
|
var group task.Group
|
||||||
group.Append0(func(ctx context.Context) error {
|
group.Append0(func(ctx context.Context) error {
|
||||||
defer cancel()
|
|
||||||
_buffer := buf.StackNewSize(dns.FixedPacketSize)
|
_buffer := buf.StackNewSize(dns.FixedPacketSize)
|
||||||
defer common.KeepAlive(_buffer)
|
defer common.KeepAlive(_buffer)
|
||||||
buffer := common.Dup(_buffer)
|
buffer := common.Dup(_buffer)
|
||||||
@@ -115,11 +114,13 @@ func (d *DNS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metada
|
|||||||
buffer.FullReset()
|
buffer.FullReset()
|
||||||
destination, err := conn.ReadPacket(buffer)
|
destination, err := conn.ReadPacket(buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
cancel(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var message mDNS.Msg
|
var message mDNS.Msg
|
||||||
err = message.Unpack(buffer.Bytes())
|
err = message.Unpack(buffer.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
cancel(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
timeout.Update()
|
timeout.Update()
|
||||||
@@ -127,17 +128,22 @@ func (d *DNS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metada
|
|||||||
go func() error {
|
go func() error {
|
||||||
response, err := d.router.Exchange(adapter.WithContext(ctx, &metadataInQuery), &message)
|
response, err := d.router.Exchange(adapter.WithContext(ctx, &metadataInQuery), &message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
cancel(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
timeout.Update()
|
timeout.Update()
|
||||||
responseBuffer := buf.NewPacket()
|
responseBuffer := buf.NewPacket()
|
||||||
n, err := response.PackBuffer(responseBuffer.FreeBytes())
|
n, err := response.PackBuffer(responseBuffer.FreeBytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
cancel(err)
|
||||||
responseBuffer.Release()
|
responseBuffer.Release()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
responseBuffer.Truncate(len(n))
|
responseBuffer.Truncate(len(n))
|
||||||
err = conn.WritePacket(responseBuffer, destination)
|
err = conn.WritePacket(responseBuffer, destination)
|
||||||
|
if err != nil {
|
||||||
|
cancel(err)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,14 +14,14 @@ import (
|
|||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
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)
|
var _ adapter.Outbound = (*HTTP)(nil)
|
||||||
|
|
||||||
type HTTP struct {
|
type HTTP struct {
|
||||||
myOutboundAdapter
|
myOutboundAdapter
|
||||||
client *http.Client
|
client *sHTTP.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHTTP(router adapter.Router, logger log.ContextLogger, tag string, options option.HTTPOutboundOptions) (*HTTP, error) {
|
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,
|
logger: logger,
|
||||||
tag: tag,
|
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
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ func (h *shadowsocksDialer) DialContext(ctx context.Context, network string, des
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &bufio.BindPacketConn{PacketConn: h.method.DialPacketConn(outConn), Addr: destination}, nil
|
return bufio.NewBindPacketConn(h.method.DialPacketConn(outConn), destination), nil
|
||||||
default:
|
default:
|
||||||
return nil, E.Extend(N.ErrUnknownNetwork, network)
|
return nil, E.Extend(N.ErrUnknownNetwork, network)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ func (h *trojanDialer) DialContext(ctx context.Context, network string, destinat
|
|||||||
case N.NetworkTCP:
|
case N.NetworkTCP:
|
||||||
return trojan.NewClientConn(conn, h.key, destination), nil
|
return trojan.NewClientConn(conn, h.key, destination), nil
|
||||||
case N.NetworkUDP:
|
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:
|
default:
|
||||||
return nil, E.Extend(N.ErrUnknownNetwork, network)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &bufio.BindPacketConn{PacketConn: packetaddr.NewConn(packetConn, destination), Addr: destination}, nil
|
return bufio.NewBindPacketConn(packetaddr.NewConn(packetConn, destination), destination), nil
|
||||||
} else {
|
} else {
|
||||||
return h.client.DialEarlyPacketConn(conn, destination)
|
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 {
|
if metadata.InboundOptions.SniffEnabled {
|
||||||
buffer := buf.NewPacket()
|
buffer := buf.NewPacket()
|
||||||
buffer.FullReset()
|
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 {
|
if sniffMetadata != nil {
|
||||||
metadata.Protocol = sniffMetadata.Protocol
|
metadata.Protocol = sniffMetadata.Protocol
|
||||||
metadata.Domain = sniffMetadata.Domain
|
metadata.Domain = sniffMetadata.Domain
|
||||||
@@ -646,6 +646,8 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
|
|||||||
} else {
|
} else {
|
||||||
r.logger.DebugContext(ctx, "sniffed protocol: ", metadata.Protocol)
|
r.logger.DebugContext(ctx, "sniffed protocol: ", metadata.Protocol)
|
||||||
}
|
}
|
||||||
|
} else if err != nil {
|
||||||
|
r.logger.TraceContext(ctx, "sniffed no protocol: ", err)
|
||||||
}
|
}
|
||||||
if !buffer.IsEmpty() {
|
if !buffer.IsEmpty() {
|
||||||
conn = bufio.NewCachedConn(conn, buffer)
|
conn = bufio.NewCachedConn(conn, buffer)
|
||||||
|
|||||||
@@ -498,7 +498,12 @@ func (c *PacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
n = copy(p, msg.Data)
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ type TLSObfs struct {
|
|||||||
func (to *TLSObfs) read(b []byte, discardN int) (int, error) {
|
func (to *TLSObfs) read(b []byte, discardN int) (int, error) {
|
||||||
buf := B.Get(discardN)
|
buf := B.Get(discardN)
|
||||||
_, err := io.ReadFull(to.Conn, buf)
|
_, err := io.ReadFull(to.Conn, buf)
|
||||||
|
B.Put(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
B.Put(buf)
|
|
||||||
|
|
||||||
sizeBuf := make([]byte, 2)
|
sizeBuf := make([]byte, 2)
|
||||||
_, err = io.ReadFull(to.Conn, sizeBuf)
|
_, err = io.ReadFull(to.Conn, sizeBuf)
|
||||||
|
|||||||
@@ -131,7 +131,11 @@ func (c *ClientPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
n = buffer.Len()
|
n = buffer.Len()
|
||||||
addr = destination.UDPAddr()
|
if destination.IsFqdn() {
|
||||||
|
addr = destination
|
||||||
|
} else {
|
||||||
|
addr = destination.UDPAddr()
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ func NewClientTransport(ctx context.Context, dialer N.Dialer, serverAddr M.Socks
|
|||||||
}
|
}
|
||||||
switch options.Type {
|
switch options.Type {
|
||||||
case C.V2RayTransportTypeHTTP:
|
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:
|
case C.V2RayTransportTypeGRPC:
|
||||||
if tlsConfig == nil {
|
if tlsConfig == nil {
|
||||||
return nil, C.ErrTLSRequired
|
return nil, C.ErrTLSRequired
|
||||||
|
|||||||
@@ -101,10 +101,10 @@ func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
client := NewGunServiceClient(clientConn).(GunServiceCustomNameClient)
|
client := NewGunServiceClient(clientConn).(GunServiceCustomNameClient)
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
ctx, cancel := common.ContextWithCancelCause(ctx)
|
||||||
stream, err := client.TunCustomName(ctx, c.serviceName)
|
stream, err := client.TunCustomName(ctx, c.serviceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cancel()
|
cancel(err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return NewGRPCConn(stream, cancel), nil
|
return NewGRPCConn(stream, cancel), nil
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package v2raygrpc
|
package v2raygrpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/common/baderror"
|
"github.com/sagernet/sing-box/common/baderror"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
"github.com/sagernet/sing/common/rw"
|
"github.com/sagernet/sing/common/rw"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -14,11 +14,11 @@ var _ net.Conn = (*GRPCConn)(nil)
|
|||||||
|
|
||||||
type GRPCConn struct {
|
type GRPCConn struct {
|
||||||
GunService
|
GunService
|
||||||
cancel context.CancelFunc
|
cancel common.ContextCancelCauseFunc
|
||||||
cache []byte
|
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 {
|
if client, isClient := service.(GunService_TunClient); isClient {
|
||||||
service = &clientConnWrapper{client}
|
service = &clientConnWrapper{client}
|
||||||
}
|
}
|
||||||
@@ -37,6 +37,7 @@ func (c *GRPCConn) Read(b []byte) (n int, err error) {
|
|||||||
hunk, err := c.Recv()
|
hunk, err := c.Recv()
|
||||||
err = baderror.WrapGRPC(err)
|
err = baderror.WrapGRPC(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
c.cancel(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
n = copy(b, hunk.Data)
|
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) {
|
func (c *GRPCConn) Write(b []byte) (n int, err error) {
|
||||||
err = baderror.WrapGRPC(c.Send(&Hunk{Data: b}))
|
err = baderror.WrapGRPC(c.Send(&Hunk{Data: b}))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
c.cancel(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return len(b), nil
|
return len(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GRPCConn) Close() error {
|
func (c *GRPCConn) Close() error {
|
||||||
c.cancel()
|
c.cancel(net.ErrClosed)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,11 @@ import (
|
|||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
"github.com/sagernet/sing-box/common/tls"
|
"github.com/sagernet/sing-box/common/tls"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
|
"github.com/sagernet/sing/common"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
|
||||||
|
"golang.org/x/net/http2"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/keepalive"
|
"google.golang.org/grpc/keepalive"
|
||||||
gM "google.golang.org/grpc/metadata"
|
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) {
|
func NewServer(ctx context.Context, options option.V2RayGRPCOptions, tlsConfig tls.ServerConfig, handler N.TCPConnectionHandler) (*Server, error) {
|
||||||
var serverOptions []grpc.ServerOption
|
var serverOptions []grpc.ServerOption
|
||||||
if tlsConfig != nil {
|
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)))
|
serverOptions = append(serverOptions, grpc.Creds(NewTLSTransportCredentials(tlsConfig)))
|
||||||
}
|
}
|
||||||
if options.IdleTimeout > 0 {
|
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 {
|
func (s *Server) Tun(server GunService_TunServer) error {
|
||||||
ctx, cancel := context.WithCancel(s.ctx)
|
ctx, cancel := common.ContextWithCancelCause(s.ctx)
|
||||||
conn := NewGRPCConn(server, cancel)
|
conn := NewGRPCConn(server, cancel)
|
||||||
var metadata M.Metadata
|
var metadata M.Metadata
|
||||||
if remotePeer, loaded := peer.FromContext(server.Context()); loaded {
|
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 {
|
} else if fErr == os.ErrInvalid {
|
||||||
fErr = nil
|
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))
|
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 {
|
func (s *Server) Serve(listener net.Listener) error {
|
||||||
if s.tlsConfig != nil {
|
if s.tlsConfig != nil {
|
||||||
if len(s.tlsConfig.NextProtos()) == 0 {
|
if !common.Contains(s.tlsConfig.NextProtos(), http2.NextProtoTLS) {
|
||||||
s.tlsConfig.SetNextProtos([]string{http2.NextProtoTLS})
|
s.tlsConfig.SetNextProtos(append([]string{"h2"}, s.tlsConfig.NextProtos()...))
|
||||||
}
|
}
|
||||||
listener = aTLS.NewListener(listener, s.tlsConfig)
|
listener = aTLS.NewListener(listener, s.tlsConfig)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
@@ -16,6 +15,7 @@ import (
|
|||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
sHTTP "github.com/sagernet/sing/protocol/http"
|
||||||
|
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
)
|
)
|
||||||
@@ -34,7 +34,7 @@ type Client struct {
|
|||||||
headers http.Header
|
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
|
var transport http.RoundTripper
|
||||||
if tlsConfig == nil {
|
if tlsConfig == nil {
|
||||||
transport = &http.Transport{
|
transport = &http.Transport{
|
||||||
@@ -77,14 +77,15 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
|
|||||||
}
|
}
|
||||||
uri.Host = serverAddr.String()
|
uri.Host = serverAddr.String()
|
||||||
uri.Path = options.Path
|
uri.Path = options.Path
|
||||||
if !strings.HasPrefix(uri.Path, "/") {
|
err := sHTTP.URLSetPath(&uri, options.Path)
|
||||||
uri.Path = "/" + uri.Path
|
if err != nil {
|
||||||
|
return nil, E.New("failed to set path: " + err.Error())
|
||||||
}
|
}
|
||||||
for key, valueList := range options.Headers {
|
for key, valueList := range options.Headers {
|
||||||
client.headers[key] = valueList
|
client.headers[key] = valueList
|
||||||
}
|
}
|
||||||
client.url = &uri
|
client.url = &uri
|
||||||
return client
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
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
|
var metadata M.Metadata
|
||||||
metadata.Source = sHttp.SourceAddress(request)
|
metadata.Source = sHttp.SourceAddress(request)
|
||||||
if h, ok := writer.(http.Hijacker); ok {
|
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()
|
conn, reader, err := h.Hijack()
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
if cacheLen := reader.Reader.Buffered(); cacheLen > 0 {
|
if cacheLen := reader.Reader.Buffered(); cacheLen > 0 {
|
||||||
cache := buf.NewSize(cacheLen)
|
cache := buf.NewSize(cacheLen)
|
||||||
_, err = cache.ReadFullFrom(reader.Reader, cacheLen)
|
_, err = cache.ReadFullFrom(reader.Reader, cacheLen)
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
conn = bufio.NewCachedConn(conn, cache)
|
conn = bufio.NewCachedConn(conn, cache)
|
||||||
}
|
}
|
||||||
|
if requestBody != nil {
|
||||||
|
conn = bufio.NewCachedConn(conn, requestBody)
|
||||||
|
}
|
||||||
s.handler.NewConnection(request.Context(), conn, metadata)
|
s.handler.NewConnection(request.Context(), conn, metadata)
|
||||||
} else {
|
} else {
|
||||||
|
writer.WriteHeader(http.StatusOK)
|
||||||
conn := NewHTTP2Wrapper(&ServerHTTPConn{
|
conn := NewHTTP2Wrapper(&ServerHTTPConn{
|
||||||
NewHTTPConn(request.Body, writer),
|
NewHTTPConn(request.Body, writer),
|
||||||
writer.(http.Flusher),
|
writer.(http.Flusher),
|
||||||
@@ -141,12 +153,19 @@ func (s *Server) fallbackRequest(ctx context.Context, writer http.ResponseWriter
|
|||||||
} else if fErr == os.ErrInvalid {
|
} else if fErr == os.ErrInvalid {
|
||||||
fErr = nil
|
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))
|
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 {
|
func (s *Server) Serve(listener net.Listener) error {
|
||||||
if s.tlsConfig != nil {
|
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)
|
listener = aTLS.NewListener(listener, s.tlsConfig)
|
||||||
}
|
}
|
||||||
return s.httpServer.Serve(listener)
|
return s.httpServer.Serve(listener)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
@@ -14,6 +13,7 @@ import (
|
|||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
sHTTP "github.com/sagernet/sing/protocol/http"
|
||||||
"github.com/sagernet/websocket"
|
"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.Host = serverAddr.String()
|
||||||
uri.Path = options.Path
|
uri.Path = options.Path
|
||||||
if !strings.HasPrefix(uri.Path, "/") {
|
err := sHTTP.URLSetPath(&uri, options.Path)
|
||||||
uri.Path = "/" + uri.Path
|
if err != nil {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
headers := make(http.Header)
|
headers := make(http.Header)
|
||||||
for key, value := range options.Headers {
|
for key, value := range options.Headers {
|
||||||
|
|||||||
@@ -69,6 +69,14 @@ func (c *WebsocketConn) SetDeadline(t time.Time) error {
|
|||||||
return os.ErrInvalid
|
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 {
|
func (c *WebsocketConn) Upstream() any {
|
||||||
return c.Conn.NetConn()
|
return c.Conn.NetConn()
|
||||||
}
|
}
|
||||||
@@ -195,24 +203,15 @@ func (c *EarlyWebsocketConn) RemoteAddr() net.Addr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *EarlyWebsocketConn) SetDeadline(t time.Time) error {
|
func (c *EarlyWebsocketConn) SetDeadline(t time.Time) error {
|
||||||
if c.conn == nil {
|
return os.ErrInvalid
|
||||||
return os.ErrInvalid
|
|
||||||
}
|
|
||||||
return c.conn.SetDeadline(t)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *EarlyWebsocketConn) SetReadDeadline(t time.Time) error {
|
func (c *EarlyWebsocketConn) SetReadDeadline(t time.Time) error {
|
||||||
if c.conn == nil {
|
return os.ErrInvalid
|
||||||
return os.ErrInvalid
|
|
||||||
}
|
|
||||||
return c.conn.SetReadDeadline(t)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *EarlyWebsocketConn) SetWriteDeadline(t time.Time) error {
|
func (c *EarlyWebsocketConn) SetWriteDeadline(t time.Time) error {
|
||||||
if c.conn == nil {
|
return os.ErrInvalid
|
||||||
return os.ErrInvalid
|
|
||||||
}
|
|
||||||
return c.conn.SetWriteDeadline(t)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *EarlyWebsocketConn) Upstream() any {
|
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)
|
wsConn, err := upgrader.Upgrade(writer, request, nil)
|
||||||
if err != 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
|
return
|
||||||
}
|
}
|
||||||
var metadata M.Metadata
|
var metadata M.Metadata
|
||||||
@@ -115,7 +115,9 @@ func (s *Server) fallbackRequest(ctx context.Context, writer http.ResponseWriter
|
|||||||
} else if fErr == os.ErrInvalid {
|
} else if fErr == os.ErrInvalid {
|
||||||
fErr = nil
|
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))
|
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 {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addr = c.destination.UDPAddr()
|
if c.destination.IsFqdn() {
|
||||||
|
addr = c.destination
|
||||||
|
} else {
|
||||||
|
addr = c.destination.UDPAddr()
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,11 @@ func (c *serverPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addr = c.destination.UDPAddr()
|
if c.destination.IsFqdn() {
|
||||||
|
addr = c.destination
|
||||||
|
} else {
|
||||||
|
addr = c.destination.UDPAddr()
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user