mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-04-13 20:28:32 +10:00
Compare commits
43 Commits
v1.11.0-al
...
v1.11.0-al
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1eff7fcca | ||
|
|
61f89206ec | ||
|
|
55b2e114f6 | ||
|
|
2be7482e32 | ||
|
|
e18b527eaa | ||
|
|
63e38cccf5 | ||
|
|
9e42012737 | ||
|
|
96dab3ba25 | ||
|
|
4d9f11d5f0 | ||
|
|
15a9876a10 | ||
|
|
8cb11bf322 | ||
|
|
edf40da07c | ||
|
|
7f99cab893 | ||
|
|
c0e48f865e | ||
|
|
0d1b3226cd | ||
|
|
26064a9fdc | ||
|
|
d8e66b9180 | ||
|
|
c59f282b7d | ||
|
|
aa35ae1736 | ||
|
|
ef2a2fdd52 | ||
|
|
9988144868 | ||
|
|
412701d4c5 | ||
|
|
b6c940af61 | ||
|
|
1edb80adcc | ||
|
|
e3ffffc645 | ||
|
|
7daf2d1716 | ||
|
|
b4f1c2a596 | ||
|
|
1df8dfcade | ||
|
|
beaab2e4db | ||
|
|
1ee7a4a272 | ||
|
|
44560f0c20 | ||
|
|
b8613de673 | ||
|
|
24496d89b1 | ||
|
|
1a230bda5d | ||
|
|
85f634d0cb | ||
|
|
b75dbc8a26 | ||
|
|
3a3ad11cb3 | ||
|
|
866be4acbd | ||
|
|
776052de20 | ||
|
|
e45763d5ba | ||
|
|
5eb8522205 | ||
|
|
c2b833a228 | ||
|
|
7f65ab8166 |
2
.github/workflows/debug.yml
vendored
2
.github/workflows/debug.yml
vendored
@@ -204,7 +204,7 @@ jobs:
|
||||
GOARM: ${{ matrix.goarm }}
|
||||
GOMIPS: ${{ matrix.gomips }}
|
||||
CGO_ENABLED: 0
|
||||
TAGS: with_gvisor,with_dhcp,with_wireguard,with_clash_api,with_quic,with_utls,with_ech
|
||||
TAGS: with_clash_api,with_quic
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4
|
||||
|
||||
14
Makefile
14
Makefile
@@ -96,7 +96,11 @@ upload_android:
|
||||
release_android: lib_android update_android_version build_android upload_android
|
||||
|
||||
publish_android:
|
||||
cd ../sing-box-for-android && ./gradlew :app:publishPlayReleaseBundle && ./gradlew --stop
|
||||
cd ../sing-box-for-android && ./gradlew :app:publishPlayReleaseBundle
|
||||
|
||||
publish_android_appcenter:
|
||||
cd ../sing-box-for-android && ./gradlew :app:appCenterAssembleAndUploadPlayRelease
|
||||
|
||||
|
||||
# TODO: find why and remove `-destination 'generic/platform=iOS'`
|
||||
build_ios:
|
||||
@@ -143,13 +147,9 @@ build_macos_dmg:
|
||||
--hide-extension "SFM.app" \
|
||||
--app-drop-link 0 0 \
|
||||
--skip-jenkins \
|
||||
--notarize "notarytool-password" \
|
||||
"../sing-box/dist/SFM/SFM.dmg" "build/SFM.System/SFM.app"
|
||||
|
||||
notarize_macos_dmg:
|
||||
xcrun notarytool submit "dist/SFM/SFM.dmg" --wait \
|
||||
--keychain-profile "notarytool-password" \
|
||||
--no-s3-acceleration
|
||||
|
||||
upload_macos_dmg:
|
||||
cd dist/SFM && \
|
||||
cp SFM.dmg "SFM-${VERSION}-universal.dmg" && \
|
||||
@@ -164,7 +164,7 @@ upload_macos_dsyms:
|
||||
cp SFM.dSYMs.zip "SFM-${VERSION}-universal.dSYMs.zip" && \
|
||||
ghr --replace --draft --prerelease "v${VERSION}" "SFM-${VERSION}-universal.dSYMs.zip"
|
||||
|
||||
release_macos_standalone: build_macos_standalone build_macos_dmg notarize_macos_dmg upload_macos_dmg upload_macos_dsyms
|
||||
release_macos_standalone: build_macos_standalone build_macos_dmg upload_macos_dmg upload_macos_dsyms
|
||||
|
||||
build_tvos:
|
||||
cd ../sing-box-for-apple && \
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package adapter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
type ConnectionManager interface {
|
||||
Start() error
|
||||
Close() error
|
||||
NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
|
||||
NewPacketConnection(ctx context.Context, this N.Dialer, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package adapter
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
)
|
||||
|
||||
type Endpoint interface {
|
||||
Lifecycle
|
||||
Type() string
|
||||
Tag() string
|
||||
Outbound
|
||||
}
|
||||
|
||||
type EndpointRegistry interface {
|
||||
option.EndpointOptionsRegistry
|
||||
Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, endpointType string, options any) (Endpoint, error)
|
||||
}
|
||||
|
||||
type EndpointManager interface {
|
||||
Lifecycle
|
||||
Endpoints() []Endpoint
|
||||
Get(tag string) (Endpoint, bool)
|
||||
Remove(tag string) error
|
||||
Create(ctx context.Context, router Router, logger log.ContextLogger, tag string, endpointType string, options any) error
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package endpoint
|
||||
|
||||
import "github.com/sagernet/sing-box/option"
|
||||
|
||||
type Adapter struct {
|
||||
endpointType string
|
||||
endpointTag string
|
||||
network []string
|
||||
dependencies []string
|
||||
}
|
||||
|
||||
func NewAdapter(endpointType string, endpointTag string, network []string, dependencies []string) Adapter {
|
||||
return Adapter{
|
||||
endpointType: endpointType,
|
||||
endpointTag: endpointTag,
|
||||
network: network,
|
||||
dependencies: dependencies,
|
||||
}
|
||||
}
|
||||
|
||||
func NewAdapterWithDialerOptions(endpointType string, endpointTag string, network []string, dialOptions option.DialerOptions) Adapter {
|
||||
var dependencies []string
|
||||
if dialOptions.Detour != "" {
|
||||
dependencies = []string{dialOptions.Detour}
|
||||
}
|
||||
return NewAdapter(endpointType, endpointTag, network, dependencies)
|
||||
}
|
||||
|
||||
func (a *Adapter) Type() string {
|
||||
return a.endpointType
|
||||
}
|
||||
|
||||
func (a *Adapter) Tag() string {
|
||||
return a.endpointTag
|
||||
}
|
||||
|
||||
func (a *Adapter) Network() []string {
|
||||
return a.network
|
||||
}
|
||||
|
||||
func (a *Adapter) Dependencies() []string {
|
||||
return a.dependencies
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
package endpoint
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/taskmonitor"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing/common"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
var _ adapter.EndpointManager = (*Manager)(nil)
|
||||
|
||||
type Manager struct {
|
||||
logger log.ContextLogger
|
||||
registry adapter.EndpointRegistry
|
||||
access sync.Mutex
|
||||
started bool
|
||||
stage adapter.StartStage
|
||||
endpoints []adapter.Endpoint
|
||||
endpointByTag map[string]adapter.Endpoint
|
||||
}
|
||||
|
||||
func NewManager(logger log.ContextLogger, registry adapter.EndpointRegistry) *Manager {
|
||||
return &Manager{
|
||||
logger: logger,
|
||||
registry: registry,
|
||||
endpointByTag: make(map[string]adapter.Endpoint),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) Start(stage adapter.StartStage) error {
|
||||
m.access.Lock()
|
||||
defer m.access.Unlock()
|
||||
if m.started && m.stage >= stage {
|
||||
panic("already started")
|
||||
}
|
||||
m.started = true
|
||||
m.stage = stage
|
||||
if stage == adapter.StartStateStart {
|
||||
// started with outbound manager
|
||||
return nil
|
||||
}
|
||||
for _, endpoint := range m.endpoints {
|
||||
err := adapter.LegacyStart(endpoint, stage)
|
||||
if err != nil {
|
||||
return E.Cause(err, stage, " endpoint/", endpoint.Type(), "[", endpoint.Tag(), "]")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) Close() error {
|
||||
m.access.Lock()
|
||||
defer m.access.Unlock()
|
||||
if !m.started {
|
||||
return nil
|
||||
}
|
||||
m.started = false
|
||||
endpoints := m.endpoints
|
||||
m.endpoints = nil
|
||||
monitor := taskmonitor.New(m.logger, C.StopTimeout)
|
||||
var err error
|
||||
for _, endpoint := range endpoints {
|
||||
monitor.Start("close endpoint/", endpoint.Type(), "[", endpoint.Tag(), "]")
|
||||
err = E.Append(err, endpoint.Close(), func(err error) error {
|
||||
return E.Cause(err, "close endpoint/", endpoint.Type(), "[", endpoint.Tag(), "]")
|
||||
})
|
||||
monitor.Finish()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) Endpoints() []adapter.Endpoint {
|
||||
m.access.Lock()
|
||||
defer m.access.Unlock()
|
||||
return m.endpoints
|
||||
}
|
||||
|
||||
func (m *Manager) Get(tag string) (adapter.Endpoint, bool) {
|
||||
m.access.Lock()
|
||||
defer m.access.Unlock()
|
||||
endpoint, found := m.endpointByTag[tag]
|
||||
return endpoint, found
|
||||
}
|
||||
|
||||
func (m *Manager) Remove(tag string) error {
|
||||
m.access.Lock()
|
||||
endpoint, found := m.endpointByTag[tag]
|
||||
if !found {
|
||||
m.access.Unlock()
|
||||
return os.ErrInvalid
|
||||
}
|
||||
delete(m.endpointByTag, tag)
|
||||
index := common.Index(m.endpoints, func(it adapter.Endpoint) bool {
|
||||
return it == endpoint
|
||||
})
|
||||
if index == -1 {
|
||||
panic("invalid endpoint index")
|
||||
}
|
||||
m.endpoints = append(m.endpoints[:index], m.endpoints[index+1:]...)
|
||||
started := m.started
|
||||
m.access.Unlock()
|
||||
if started {
|
||||
return endpoint.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) error {
|
||||
endpoint, err := m.registry.Create(ctx, router, logger, tag, outboundType, options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.access.Lock()
|
||||
defer m.access.Unlock()
|
||||
if m.started {
|
||||
for _, stage := range adapter.ListStartStages {
|
||||
err = adapter.LegacyStart(endpoint, stage)
|
||||
if err != nil {
|
||||
return E.Cause(err, stage, " endpoint/", endpoint.Type(), "[", endpoint.Tag(), "]")
|
||||
}
|
||||
}
|
||||
}
|
||||
if existsEndpoint, loaded := m.endpointByTag[tag]; loaded {
|
||||
if m.started {
|
||||
err = existsEndpoint.Close()
|
||||
if err != nil {
|
||||
return E.Cause(err, "close endpoint/", existsEndpoint.Type(), "[", existsEndpoint.Tag(), "]")
|
||||
}
|
||||
}
|
||||
existsIndex := common.Index(m.endpoints, func(it adapter.Endpoint) bool {
|
||||
return it == existsEndpoint
|
||||
})
|
||||
if existsIndex == -1 {
|
||||
panic("invalid endpoint index")
|
||||
}
|
||||
m.endpoints = append(m.endpoints[:existsIndex], m.endpoints[existsIndex+1:]...)
|
||||
}
|
||||
m.endpoints = append(m.endpoints, endpoint)
|
||||
m.endpointByTag[tag] = endpoint
|
||||
return nil
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package endpoint
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing/common"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
type ConstructorFunc[T any] func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options T) (adapter.Endpoint, error)
|
||||
|
||||
func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
|
||||
registry.register(outboundType, func() any {
|
||||
return new(Options)
|
||||
}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, rawOptions any) (adapter.Endpoint, error) {
|
||||
var options *Options
|
||||
if rawOptions != nil {
|
||||
options = rawOptions.(*Options)
|
||||
}
|
||||
return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options))
|
||||
})
|
||||
}
|
||||
|
||||
var _ adapter.EndpointRegistry = (*Registry)(nil)
|
||||
|
||||
type (
|
||||
optionsConstructorFunc func() any
|
||||
constructorFunc func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Endpoint, error)
|
||||
)
|
||||
|
||||
type Registry struct {
|
||||
access sync.Mutex
|
||||
optionsType map[string]optionsConstructorFunc
|
||||
constructor map[string]constructorFunc
|
||||
}
|
||||
|
||||
func NewRegistry() *Registry {
|
||||
return &Registry{
|
||||
optionsType: make(map[string]optionsConstructorFunc),
|
||||
constructor: make(map[string]constructorFunc),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Registry) CreateOptions(outboundType string) (any, bool) {
|
||||
m.access.Lock()
|
||||
defer m.access.Unlock()
|
||||
optionsConstructor, loaded := m.optionsType[outboundType]
|
||||
if !loaded {
|
||||
return nil, false
|
||||
}
|
||||
return optionsConstructor(), true
|
||||
}
|
||||
|
||||
func (m *Registry) Create(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, outboundType string, options any) (adapter.Endpoint, error) {
|
||||
m.access.Lock()
|
||||
defer m.access.Unlock()
|
||||
constructor, loaded := m.constructor[outboundType]
|
||||
if !loaded {
|
||||
return nil, E.New("outbound type not found: " + outboundType)
|
||||
}
|
||||
return constructor(ctx, router, logger, tag, options)
|
||||
}
|
||||
|
||||
func (m *Registry) register(outboundType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
|
||||
m.access.Lock()
|
||||
defer m.access.Unlock()
|
||||
m.optionsType[outboundType] = optionsConstructor
|
||||
m.constructor[outboundType] = constructor
|
||||
}
|
||||
@@ -46,9 +46,6 @@ type PacketConnectionHandlerEx interface {
|
||||
NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
|
||||
}
|
||||
|
||||
// Deprecated: use TCPConnectionHandlerEx instead
|
||||
//
|
||||
//nolint:staticcheck
|
||||
type UpstreamHandlerAdapter interface {
|
||||
N.TCPConnectionHandler
|
||||
N.UDPConnectionHandler
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
type Inbound interface {
|
||||
Lifecycle
|
||||
Service
|
||||
Type() string
|
||||
Tag() string
|
||||
}
|
||||
@@ -61,12 +61,10 @@ type InboundContext struct {
|
||||
// cache
|
||||
|
||||
// Deprecated: implement in rule action
|
||||
InboundDetour string
|
||||
LastInbound string
|
||||
OriginDestination M.Socksaddr
|
||||
RouteOriginalDestination M.Socksaddr
|
||||
// Deprecated: to be removed
|
||||
//nolint:staticcheck
|
||||
InboundDetour string
|
||||
LastInbound string
|
||||
OriginDestination M.Socksaddr
|
||||
// Deprecated
|
||||
InboundOptions option.InboundOptions
|
||||
UDPDisableDomainUnmapping bool
|
||||
UDPConnect bool
|
||||
|
||||
@@ -18,7 +18,6 @@ var _ adapter.InboundManager = (*Manager)(nil)
|
||||
type Manager struct {
|
||||
logger log.ContextLogger
|
||||
registry adapter.InboundRegistry
|
||||
endpoint adapter.EndpointManager
|
||||
access sync.Mutex
|
||||
started bool
|
||||
stage adapter.StartStage
|
||||
@@ -26,11 +25,10 @@ type Manager struct {
|
||||
inboundByTag map[string]adapter.Inbound
|
||||
}
|
||||
|
||||
func NewManager(logger log.ContextLogger, registry adapter.InboundRegistry, endpoint adapter.EndpointManager) *Manager {
|
||||
func NewManager(logger log.ContextLogger, registry adapter.InboundRegistry) *Manager {
|
||||
return &Manager{
|
||||
logger: logger,
|
||||
registry: registry,
|
||||
endpoint: endpoint,
|
||||
inboundByTag: make(map[string]adapter.Inbound),
|
||||
}
|
||||
}
|
||||
@@ -81,12 +79,9 @@ func (m *Manager) Inbounds() []adapter.Inbound {
|
||||
|
||||
func (m *Manager) Get(tag string) (adapter.Inbound, bool) {
|
||||
m.access.Lock()
|
||||
defer m.access.Unlock()
|
||||
inbound, found := m.inboundByTag[tag]
|
||||
m.access.Unlock()
|
||||
if found {
|
||||
return inbound, true
|
||||
}
|
||||
return m.endpoint.Get(tag)
|
||||
return inbound, found
|
||||
}
|
||||
|
||||
func (m *Manager) Remove(tag string) error {
|
||||
|
||||
@@ -15,12 +15,8 @@ type ConstructorFunc[T any] func(ctx context.Context, router adapter.Router, log
|
||||
func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
|
||||
registry.register(outboundType, func() any {
|
||||
return new(Options)
|
||||
}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, rawOptions any) (adapter.Inbound, error) {
|
||||
var options *Options
|
||||
if rawOptions != nil {
|
||||
options = rawOptions.(*Options)
|
||||
}
|
||||
return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options))
|
||||
}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Inbound, error) {
|
||||
return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options.(*Options)))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package adapter
|
||||
|
||||
func LegacyStart(starter any, stage StartStage) error {
|
||||
if lifecycle, isLifecycle := starter.(Lifecycle); isLifecycle {
|
||||
return lifecycle.Start(stage)
|
||||
}
|
||||
switch stage {
|
||||
case StartStateInitialize:
|
||||
if preStarter, isPreStarter := starter.(interface {
|
||||
|
||||
@@ -5,35 +5,35 @@ import (
|
||||
)
|
||||
|
||||
type Adapter struct {
|
||||
outboundType string
|
||||
outboundTag string
|
||||
protocol string
|
||||
network []string
|
||||
tag string
|
||||
dependencies []string
|
||||
}
|
||||
|
||||
func NewAdapter(outboundType string, outboundTag string, network []string, dependencies []string) Adapter {
|
||||
func NewAdapter(protocol string, network []string, tag string, dependencies []string) Adapter {
|
||||
return Adapter{
|
||||
outboundType: outboundType,
|
||||
outboundTag: outboundTag,
|
||||
protocol: protocol,
|
||||
network: network,
|
||||
tag: tag,
|
||||
dependencies: dependencies,
|
||||
}
|
||||
}
|
||||
|
||||
func NewAdapterWithDialerOptions(outboundType string, outboundTag string, network []string, dialOptions option.DialerOptions) Adapter {
|
||||
func NewAdapterWithDialerOptions(protocol string, network []string, tag string, dialOptions option.DialerOptions) Adapter {
|
||||
var dependencies []string
|
||||
if dialOptions.Detour != "" {
|
||||
dependencies = []string{dialOptions.Detour}
|
||||
}
|
||||
return NewAdapter(outboundType, outboundTag, network, dependencies)
|
||||
return NewAdapter(protocol, network, tag, dependencies)
|
||||
}
|
||||
|
||||
func (a *Adapter) Type() string {
|
||||
return a.outboundType
|
||||
return a.protocol
|
||||
}
|
||||
|
||||
func (a *Adapter) Tag() string {
|
||||
return a.outboundTag
|
||||
return a.tag
|
||||
}
|
||||
|
||||
func (a *Adapter) Network() []string {
|
||||
|
||||
@@ -25,7 +25,11 @@ func NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata a
|
||||
var outConn net.Conn
|
||||
var err error
|
||||
if len(metadata.DestinationAddresses) > 0 {
|
||||
outConn, err = dialer.DialSerialNetwork(ctx, this, N.NetworkTCP, metadata.Destination, metadata.DestinationAddresses, metadata.NetworkStrategy, metadata.NetworkType, metadata.FallbackNetworkType, metadata.FallbackDelay)
|
||||
if parallelDialer, isParallelDialer := this.(dialer.ParallelInterfaceDialer); isParallelDialer {
|
||||
outConn, err = dialer.DialSerialNetwork(ctx, parallelDialer, N.NetworkTCP, metadata.Destination, metadata.DestinationAddresses, metadata.NetworkStrategy, metadata.NetworkType, metadata.FallbackNetworkType, metadata.FallbackDelay)
|
||||
} else {
|
||||
outConn, err = N.DialSerial(ctx, this, N.NetworkTCP, metadata.Destination, metadata.DestinationAddresses)
|
||||
}
|
||||
} else {
|
||||
outConn, err = this.DialContext(ctx, N.NetworkTCP, metadata.Destination)
|
||||
}
|
||||
@@ -69,7 +73,11 @@ func NewPacketConnection(ctx context.Context, this N.Dialer, conn N.PacketConn,
|
||||
}
|
||||
} else {
|
||||
if len(metadata.DestinationAddresses) > 0 {
|
||||
outPacketConn, destinationAddress, err = dialer.ListenSerialNetworkPacket(ctx, this, metadata.Destination, metadata.DestinationAddresses, metadata.NetworkStrategy, metadata.NetworkType, metadata.FallbackNetworkType, metadata.FallbackDelay)
|
||||
if parallelDialer, isParallelDialer := this.(dialer.ParallelInterfaceDialer); isParallelDialer {
|
||||
outPacketConn, destinationAddress, err = dialer.ListenSerialNetworkPacket(ctx, parallelDialer, metadata.Destination, metadata.DestinationAddresses, metadata.NetworkStrategy, metadata.NetworkType, metadata.FallbackNetworkType, metadata.FallbackDelay)
|
||||
} else {
|
||||
outPacketConn, destinationAddress, err = N.ListenSerial(ctx, this, metadata.Destination, metadata.DestinationAddresses)
|
||||
}
|
||||
} else {
|
||||
outPacketConn, err = this.ListenPacket(ctx, metadata.Destination)
|
||||
}
|
||||
@@ -83,17 +91,11 @@ func NewPacketConnection(ctx context.Context, this N.Dialer, conn N.PacketConn,
|
||||
return err
|
||||
}
|
||||
if destinationAddress.IsValid() {
|
||||
var originDestination M.Socksaddr
|
||||
if metadata.RouteOriginalDestination.IsValid() {
|
||||
originDestination = metadata.RouteOriginalDestination
|
||||
} else {
|
||||
originDestination = metadata.Destination
|
||||
}
|
||||
if metadata.Destination != M.SocksaddrFrom(destinationAddress, metadata.Destination.Port) {
|
||||
if metadata.Destination.IsFqdn() {
|
||||
if metadata.UDPDisableDomainUnmapping {
|
||||
outPacketConn = bufio.NewUnidirectionalNATPacketConn(bufio.NewPacketConn(outPacketConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), originDestination)
|
||||
outPacketConn = bufio.NewUnidirectionalNATPacketConn(bufio.NewPacketConn(outPacketConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), metadata.Destination)
|
||||
} else {
|
||||
outPacketConn = bufio.NewNATPacketConn(bufio.NewPacketConn(outPacketConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), originDestination)
|
||||
outPacketConn = bufio.NewNATPacketConn(bufio.NewPacketConn(outPacketConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), metadata.Destination)
|
||||
}
|
||||
}
|
||||
if natConn, loaded := common.Cast[bufio.NATPacketConn](conn); loaded {
|
||||
|
||||
@@ -21,7 +21,6 @@ var _ adapter.OutboundManager = (*Manager)(nil)
|
||||
type Manager struct {
|
||||
logger log.ContextLogger
|
||||
registry adapter.OutboundRegistry
|
||||
endpoint adapter.EndpointManager
|
||||
defaultTag string
|
||||
access sync.Mutex
|
||||
started bool
|
||||
@@ -33,11 +32,10 @@ type Manager struct {
|
||||
defaultOutboundFallback adapter.Outbound
|
||||
}
|
||||
|
||||
func NewManager(logger logger.ContextLogger, registry adapter.OutboundRegistry, endpoint adapter.EndpointManager, defaultTag string) *Manager {
|
||||
func NewManager(logger logger.ContextLogger, registry adapter.OutboundRegistry, defaultTag string) *Manager {
|
||||
return &Manager{
|
||||
logger: logger,
|
||||
registry: registry,
|
||||
endpoint: endpoint,
|
||||
defaultTag: defaultTag,
|
||||
outboundByTag: make(map[string]adapter.Outbound),
|
||||
dependByTag: make(map[string][]string),
|
||||
@@ -58,14 +56,7 @@ func (m *Manager) Start(stage adapter.StartStage) error {
|
||||
outbounds := m.outbounds
|
||||
m.access.Unlock()
|
||||
if stage == adapter.StartStateStart {
|
||||
if m.defaultTag != "" && m.defaultOutbound == nil {
|
||||
defaultEndpoint, loaded := m.endpoint.Get(m.defaultTag)
|
||||
if !loaded {
|
||||
return E.New("default outbound not found: ", m.defaultTag)
|
||||
}
|
||||
m.defaultOutbound = defaultEndpoint
|
||||
}
|
||||
return m.startOutbounds(append(outbounds, common.Map(m.endpoint.Endpoints(), func(it adapter.Endpoint) adapter.Outbound { return it })...))
|
||||
return m.startOutbounds(outbounds)
|
||||
} else {
|
||||
for _, outbound := range outbounds {
|
||||
err := adapter.LegacyStart(outbound, stage)
|
||||
@@ -96,14 +87,7 @@ func (m *Manager) startOutbounds(outbounds []adapter.Outbound) error {
|
||||
}
|
||||
started[outboundTag] = true
|
||||
canContinue = true
|
||||
if starter, isStarter := outboundToStart.(adapter.Lifecycle); isStarter {
|
||||
monitor.Start("start outbound/", outboundToStart.Type(), "[", outboundTag, "]")
|
||||
err := starter.Start(adapter.StartStateStart)
|
||||
monitor.Finish()
|
||||
if err != nil {
|
||||
return E.Cause(err, "start outbound/", outboundToStart.Type(), "[", outboundTag, "]")
|
||||
}
|
||||
} else if starter, isStarter := outboundToStart.(interface {
|
||||
if starter, isStarter := outboundToStart.(interface {
|
||||
Start() error
|
||||
}); isStarter {
|
||||
monitor.Start("start outbound/", outboundToStart.Type(), "[", outboundTag, "]")
|
||||
@@ -176,12 +160,9 @@ func (m *Manager) Outbounds() []adapter.Outbound {
|
||||
|
||||
func (m *Manager) Outbound(tag string) (adapter.Outbound, bool) {
|
||||
m.access.Lock()
|
||||
defer m.access.Unlock()
|
||||
outbound, found := m.outboundByTag[tag]
|
||||
m.access.Unlock()
|
||||
if found {
|
||||
return outbound, true
|
||||
}
|
||||
return m.endpoint.Get(tag)
|
||||
return outbound, found
|
||||
}
|
||||
|
||||
func (m *Manager) Default() adapter.Outbound {
|
||||
|
||||
@@ -15,12 +15,8 @@ type ConstructorFunc[T any] func(ctx context.Context, router adapter.Router, log
|
||||
func Register[Options any](registry *Registry, outboundType string, constructor ConstructorFunc[Options]) {
|
||||
registry.register(outboundType, func() any {
|
||||
return new(Options)
|
||||
}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, rawOptions any) (adapter.Outbound, error) {
|
||||
var options *Options
|
||||
if rawOptions != nil {
|
||||
options = rawOptions.(*Options)
|
||||
}
|
||||
return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options))
|
||||
}, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options any) (adapter.Outbound, error) {
|
||||
return constructor(ctx, router, logger, tag, common.PtrValueOrDefault(options.(*Options)))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@ type (
|
||||
)
|
||||
|
||||
// Deprecated
|
||||
//
|
||||
//nolint:staticcheck
|
||||
func NewUpstreamHandler(
|
||||
metadata InboundContext,
|
||||
connectionHandler ConnectionHandlerFunc,
|
||||
@@ -36,9 +34,7 @@ func NewUpstreamHandler(
|
||||
|
||||
var _ UpstreamHandlerAdapter = (*myUpstreamHandlerWrapper)(nil)
|
||||
|
||||
// Deprecated: use myUpstreamHandlerWrapperEx instead.
|
||||
//
|
||||
//nolint:staticcheck
|
||||
// Deprecated
|
||||
type myUpstreamHandlerWrapper struct {
|
||||
metadata InboundContext
|
||||
connectionHandler ConnectionHandlerFunc
|
||||
@@ -46,7 +42,6 @@ type myUpstreamHandlerWrapper struct {
|
||||
errorHandler E.Handler
|
||||
}
|
||||
|
||||
// Deprecated: use myUpstreamHandlerWrapperEx instead.
|
||||
func (w *myUpstreamHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
|
||||
myMetadata := w.metadata
|
||||
if metadata.Source.IsValid() {
|
||||
@@ -58,7 +53,6 @@ func (w *myUpstreamHandlerWrapper) NewConnection(ctx context.Context, conn net.C
|
||||
return w.connectionHandler(ctx, conn, myMetadata)
|
||||
}
|
||||
|
||||
// Deprecated: use myUpstreamHandlerWrapperEx instead.
|
||||
func (w *myUpstreamHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
|
||||
myMetadata := w.metadata
|
||||
if metadata.Source.IsValid() {
|
||||
@@ -70,12 +64,11 @@ func (w *myUpstreamHandlerWrapper) NewPacketConnection(ctx context.Context, conn
|
||||
return w.packetHandler(ctx, conn, myMetadata)
|
||||
}
|
||||
|
||||
// Deprecated: use myUpstreamHandlerWrapperEx instead.
|
||||
func (w *myUpstreamHandlerWrapper) NewError(ctx context.Context, err error) {
|
||||
w.errorHandler.NewError(ctx, err)
|
||||
}
|
||||
|
||||
// Deprecated: removed
|
||||
// Deprecated
|
||||
func UpstreamMetadata(metadata InboundContext) M.Metadata {
|
||||
return M.Metadata{
|
||||
Source: metadata.Source,
|
||||
@@ -83,14 +76,14 @@ func UpstreamMetadata(metadata InboundContext) M.Metadata {
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated: Use NewUpstreamContextHandlerEx instead.
|
||||
// Deprecated
|
||||
type myUpstreamContextHandlerWrapper struct {
|
||||
connectionHandler ConnectionHandlerFunc
|
||||
packetHandler PacketConnectionHandlerFunc
|
||||
errorHandler E.Handler
|
||||
}
|
||||
|
||||
// Deprecated: Use NewUpstreamContextHandlerEx instead.
|
||||
// Deprecated
|
||||
func NewUpstreamContextHandler(
|
||||
connectionHandler ConnectionHandlerFunc,
|
||||
packetHandler PacketConnectionHandlerFunc,
|
||||
@@ -103,7 +96,6 @@ func NewUpstreamContextHandler(
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated: Use NewUpstreamContextHandlerEx instead.
|
||||
func (w *myUpstreamContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
|
||||
myMetadata := ContextFrom(ctx)
|
||||
if metadata.Source.IsValid() {
|
||||
@@ -115,7 +107,6 @@ func (w *myUpstreamContextHandlerWrapper) NewConnection(ctx context.Context, con
|
||||
return w.connectionHandler(ctx, conn, *myMetadata)
|
||||
}
|
||||
|
||||
// Deprecated: Use NewUpstreamContextHandlerEx instead.
|
||||
func (w *myUpstreamContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
|
||||
myMetadata := ContextFrom(ctx)
|
||||
if metadata.Source.IsValid() {
|
||||
@@ -127,7 +118,6 @@ func (w *myUpstreamContextHandlerWrapper) NewPacketConnection(ctx context.Contex
|
||||
return w.packetHandler(ctx, conn, *myMetadata)
|
||||
}
|
||||
|
||||
// Deprecated: Use NewUpstreamContextHandlerEx instead.
|
||||
func (w *myUpstreamContextHandlerWrapper) NewError(ctx context.Context, err error) {
|
||||
w.errorHandler.NewError(ctx, err)
|
||||
}
|
||||
@@ -159,15 +149,12 @@ func NewRouteContextHandler(
|
||||
var _ UpstreamHandlerAdapter = (*routeHandlerWrapper)(nil)
|
||||
|
||||
// Deprecated: Use ConnectionRouterEx instead.
|
||||
//
|
||||
//nolint:staticcheck
|
||||
type routeHandlerWrapper struct {
|
||||
metadata InboundContext
|
||||
router ConnectionRouter
|
||||
logger logger.ContextLogger
|
||||
}
|
||||
|
||||
// Deprecated: Use ConnectionRouterEx instead.
|
||||
func (w *routeHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
|
||||
myMetadata := w.metadata
|
||||
if metadata.Source.IsValid() {
|
||||
@@ -179,7 +166,6 @@ func (w *routeHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn,
|
||||
return w.router.RouteConnection(ctx, conn, myMetadata)
|
||||
}
|
||||
|
||||
// Deprecated: Use ConnectionRouterEx instead.
|
||||
func (w *routeHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
|
||||
myMetadata := w.metadata
|
||||
if metadata.Source.IsValid() {
|
||||
@@ -191,7 +177,6 @@ func (w *routeHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.Pa
|
||||
return w.router.RoutePacketConnection(ctx, conn, myMetadata)
|
||||
}
|
||||
|
||||
// Deprecated: Use ConnectionRouterEx instead.
|
||||
func (w *routeHandlerWrapper) NewError(ctx context.Context, err error) {
|
||||
w.logger.ErrorContext(ctx, err)
|
||||
}
|
||||
@@ -204,7 +189,6 @@ type routeContextHandlerWrapper struct {
|
||||
logger logger.ContextLogger
|
||||
}
|
||||
|
||||
// Deprecated: Use ConnectionRouterEx instead.
|
||||
func (w *routeContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
|
||||
myMetadata := ContextFrom(ctx)
|
||||
if metadata.Source.IsValid() {
|
||||
@@ -216,7 +200,6 @@ func (w *routeContextHandlerWrapper) NewConnection(ctx context.Context, conn net
|
||||
return w.router.RouteConnection(ctx, conn, *myMetadata)
|
||||
}
|
||||
|
||||
// Deprecated: Use ConnectionRouterEx instead.
|
||||
func (w *routeContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
|
||||
myMetadata := ContextFrom(ctx)
|
||||
if metadata.Source.IsValid() {
|
||||
@@ -228,7 +211,6 @@ func (w *routeContextHandlerWrapper) NewPacketConnection(ctx context.Context, co
|
||||
return w.router.RoutePacketConnection(ctx, conn, *myMetadata)
|
||||
}
|
||||
|
||||
// Deprecated: Use ConnectionRouterEx instead.
|
||||
func (w *routeContextHandlerWrapper) NewError(ctx context.Context, err error) {
|
||||
w.logger.ErrorContext(ctx, err)
|
||||
}
|
||||
|
||||
73
box.go
73
box.go
@@ -9,7 +9,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/adapter/endpoint"
|
||||
"github.com/sagernet/sing-box/adapter/inbound"
|
||||
"github.com/sagernet/sing-box/adapter/outbound"
|
||||
"github.com/sagernet/sing-box/common/dialer"
|
||||
@@ -37,11 +36,9 @@ type Box struct {
|
||||
logFactory log.Factory
|
||||
logger log.ContextLogger
|
||||
network *route.NetworkManager
|
||||
endpoint *endpoint.Manager
|
||||
router *route.Router
|
||||
inbound *inbound.Manager
|
||||
outbound *outbound.Manager
|
||||
connection *route.ConnectionManager
|
||||
router *route.Router
|
||||
services []adapter.LifecycleService
|
||||
done chan struct{}
|
||||
}
|
||||
@@ -56,7 +53,6 @@ func Context(
|
||||
ctx context.Context,
|
||||
inboundRegistry adapter.InboundRegistry,
|
||||
outboundRegistry adapter.OutboundRegistry,
|
||||
endpointRegistry adapter.EndpointRegistry,
|
||||
) context.Context {
|
||||
if service.FromContext[option.InboundOptionsRegistry](ctx) == nil ||
|
||||
service.FromContext[adapter.InboundRegistry](ctx) == nil {
|
||||
@@ -68,11 +64,6 @@ func Context(
|
||||
ctx = service.ContextWith[option.OutboundOptionsRegistry](ctx, outboundRegistry)
|
||||
ctx = service.ContextWith[adapter.OutboundRegistry](ctx, outboundRegistry)
|
||||
}
|
||||
if service.FromContext[option.EndpointOptionsRegistry](ctx) == nil ||
|
||||
service.FromContext[adapter.EndpointRegistry](ctx) == nil {
|
||||
ctx = service.ContextWith[option.EndpointOptionsRegistry](ctx, endpointRegistry)
|
||||
ctx = service.ContextWith[adapter.EndpointRegistry](ctx, endpointRegistry)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
@@ -84,16 +75,12 @@ func New(options Options) (*Box, error) {
|
||||
}
|
||||
ctx = service.ContextWithDefaultRegistry(ctx)
|
||||
|
||||
endpointRegistry := service.FromContext[adapter.EndpointRegistry](ctx)
|
||||
inboundRegistry := service.FromContext[adapter.InboundRegistry](ctx)
|
||||
outboundRegistry := service.FromContext[adapter.OutboundRegistry](ctx)
|
||||
|
||||
if endpointRegistry == nil {
|
||||
return nil, E.New("missing endpoint registry in context")
|
||||
}
|
||||
if inboundRegistry == nil {
|
||||
return nil, E.New("missing inbound registry in context")
|
||||
}
|
||||
|
||||
outboundRegistry := service.FromContext[adapter.OutboundRegistry](ctx)
|
||||
if outboundRegistry == nil {
|
||||
return nil, E.New("missing outbound registry in context")
|
||||
}
|
||||
@@ -131,10 +118,8 @@ func New(options Options) (*Box, error) {
|
||||
}
|
||||
|
||||
routeOptions := common.PtrValueOrDefault(options.Route)
|
||||
endpointManager := endpoint.NewManager(logFactory.NewLogger("endpoint"), endpointRegistry)
|
||||
inboundManager := inbound.NewManager(logFactory.NewLogger("inbound"), inboundRegistry, endpointManager)
|
||||
outboundManager := outbound.NewManager(logFactory.NewLogger("outbound"), outboundRegistry, endpointManager, routeOptions.Final)
|
||||
service.MustRegister[adapter.EndpointManager](ctx, endpointManager)
|
||||
inboundManager := inbound.NewManager(logFactory.NewLogger("inbound"), inboundRegistry)
|
||||
outboundManager := outbound.NewManager(logFactory.NewLogger("outbound"), outboundRegistry, routeOptions.Final)
|
||||
service.MustRegister[adapter.InboundManager](ctx, inboundManager)
|
||||
service.MustRegister[adapter.OutboundManager](ctx, outboundManager)
|
||||
|
||||
@@ -143,28 +128,28 @@ func New(options Options) (*Box, error) {
|
||||
return nil, E.Cause(err, "initialize network manager")
|
||||
}
|
||||
service.MustRegister[adapter.NetworkManager](ctx, networkManager)
|
||||
connectionManager := route.NewConnectionManager(logFactory.NewLogger("connection"))
|
||||
service.MustRegister[adapter.ConnectionManager](ctx, connectionManager)
|
||||
router, err := route.NewRouter(ctx, logFactory, routeOptions, common.PtrValueOrDefault(options.DNS))
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "initialize router")
|
||||
}
|
||||
for i, endpointOptions := range options.Endpoints {
|
||||
var tag string
|
||||
if endpointOptions.Tag != "" {
|
||||
tag = endpointOptions.Tag
|
||||
} else {
|
||||
tag = F.ToString(i)
|
||||
//nolint:staticcheck
|
||||
if len(options.LegacyInbounds) > 0 {
|
||||
for _, legacyInbound := range options.LegacyInbounds {
|
||||
options.Inbounds = append(options.Inbounds, option.Inbound{
|
||||
Type: legacyInbound.Type,
|
||||
Tag: legacyInbound.Tag,
|
||||
Options: common.Must1(legacyInbound.RawOptions()),
|
||||
})
|
||||
}
|
||||
err = endpointManager.Create(ctx,
|
||||
router,
|
||||
logFactory.NewLogger(F.ToString("endpoint/", endpointOptions.Type, "[", tag, "]")),
|
||||
tag,
|
||||
endpointOptions.Type,
|
||||
endpointOptions.Options,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "initialize inbound[", i, "]")
|
||||
}
|
||||
//nolint:staticcheck
|
||||
if len(options.LegacyOutbounds) > 0 {
|
||||
for _, legacyOutbound := range options.LegacyOutbounds {
|
||||
options.Outbounds = append(options.Outbounds, option.Outbound{
|
||||
Type: legacyOutbound.Type,
|
||||
Tag: legacyOutbound.Tag,
|
||||
Options: common.Must1(legacyOutbound.RawOptions()),
|
||||
})
|
||||
}
|
||||
}
|
||||
for i, inboundOptions := range options.Inbounds {
|
||||
@@ -273,11 +258,9 @@ func New(options Options) (*Box, error) {
|
||||
}
|
||||
return &Box{
|
||||
network: networkManager,
|
||||
endpoint: endpointManager,
|
||||
router: router,
|
||||
inbound: inboundManager,
|
||||
outbound: outboundManager,
|
||||
connection: connectionManager,
|
||||
router: router,
|
||||
createdAt: createdAt,
|
||||
logFactory: logFactory,
|
||||
logger: logFactory.Logger(),
|
||||
@@ -336,7 +319,7 @@ func (s *Box) preStart() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = adapter.Start(adapter.StartStateInitialize, s.network, s.router, s.outbound, s.inbound, s.endpoint)
|
||||
err = adapter.Start(adapter.StartStateInitialize, s.network, s.router, s.outbound, s.inbound)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -360,11 +343,7 @@ func (s *Box) start() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = adapter.Start(adapter.StartStateStart, s.endpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = adapter.Start(adapter.StartStatePostStart, s.outbound, s.network, s.router, s.inbound, s.endpoint)
|
||||
err = adapter.Start(adapter.StartStatePostStart, s.outbound, s.network, s.router, s.inbound)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -372,7 +351,7 @@ func (s *Box) start() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = adapter.Start(adapter.StartStateStarted, s.network, s.router, s.outbound, s.inbound, s.endpoint)
|
||||
err = adapter.Start(adapter.StartStateStarted, s.network, s.router, s.outbound, s.inbound)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Submodule clients/android updated: ea460ea5d1...45a1f5f0aa
Submodule clients/apple updated: 286f9717cb...c7d9b49de7
@@ -69,5 +69,5 @@ func preRun(cmd *cobra.Command, args []string) {
|
||||
configPaths = append(configPaths, "config.json")
|
||||
}
|
||||
globalCtx = service.ContextWith(globalCtx, deprecated.NewStderrManager(log.StdLogger()))
|
||||
globalCtx = box.Context(globalCtx, include.InboundRegistry(), include.OutboundRegistry(), include.EndpointRegistry())
|
||||
globalCtx = box.Context(globalCtx, include.InboundRegistry(), include.OutboundRegistry())
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ func (d *DefaultDialer) ListenSerialInterfacePacket(ctx context.Context, destina
|
||||
}
|
||||
|
||||
func (d *DefaultDialer) ListenPacketCompat(network, address string) (net.PacketConn, error) {
|
||||
return trackPacketConn(d.udpListener.ListenPacket(context.Background(), network, address))
|
||||
return trackPacketConn(d.listenSerialInterfacePacket(context.Background(), d.udpListener, network, address, d.networkStrategy, d.networkType, d.fallbackNetworkType, d.networkFallbackDelay))
|
||||
}
|
||||
|
||||
func trackConn(conn net.Conn, err error) (net.Conn, error) {
|
||||
|
||||
@@ -149,6 +149,9 @@ func (d *DefaultDialer) listenSerialInterfacePacket(ctx context.Context, listene
|
||||
if len(primaryInterfaces)+len(fallbackInterfaces) == 0 {
|
||||
return nil, E.New("no available network interface")
|
||||
}
|
||||
if fallbackDelay == 0 {
|
||||
fallbackDelay = N.DefaultFallbackDelay
|
||||
}
|
||||
var errors []error
|
||||
for _, primaryInterface := range primaryInterfaces {
|
||||
perNetListener := listener
|
||||
|
||||
@@ -13,27 +13,17 @@ import (
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
func DialSerialNetwork(ctx context.Context, dialer N.Dialer, network string, destination M.Socksaddr, destinationAddresses []netip.Addr, strategy C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.Conn, error) {
|
||||
func DialSerialNetwork(ctx context.Context, dialer ParallelInterfaceDialer, network string, destination M.Socksaddr, destinationAddresses []netip.Addr, strategy C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.Conn, error) {
|
||||
if parallelDialer, isParallel := dialer.(ParallelNetworkDialer); isParallel {
|
||||
return parallelDialer.DialParallelNetwork(ctx, network, destination, destinationAddresses, strategy, interfaceType, fallbackInterfaceType, fallbackDelay)
|
||||
}
|
||||
var errors []error
|
||||
if parallelDialer, isParallel := dialer.(ParallelInterfaceDialer); isParallel {
|
||||
for _, address := range destinationAddresses {
|
||||
conn, err := parallelDialer.DialParallelInterface(ctx, network, M.SocksaddrFrom(address, destination.Port), strategy, interfaceType, fallbackInterfaceType, fallbackDelay)
|
||||
if err == nil {
|
||||
return conn, nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
}
|
||||
} else {
|
||||
for _, address := range destinationAddresses {
|
||||
conn, err := dialer.DialContext(ctx, network, M.SocksaddrFrom(address, destination.Port))
|
||||
if err == nil {
|
||||
return conn, nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
for _, address := range destinationAddresses {
|
||||
conn, err := dialer.DialParallelInterface(ctx, network, M.SocksaddrFrom(address, destination.Port), strategy, interfaceType, fallbackInterfaceType, fallbackDelay)
|
||||
if err == nil {
|
||||
return conn, nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
}
|
||||
return nil, E.Errors(errors...)
|
||||
}
|
||||
@@ -116,27 +106,17 @@ func DialParallelNetwork(ctx context.Context, dialer ParallelInterfaceDialer, ne
|
||||
}
|
||||
}
|
||||
|
||||
func ListenSerialNetworkPacket(ctx context.Context, dialer N.Dialer, destination M.Socksaddr, destinationAddresses []netip.Addr, strategy C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.PacketConn, netip.Addr, error) {
|
||||
func ListenSerialNetworkPacket(ctx context.Context, dialer ParallelInterfaceDialer, destination M.Socksaddr, destinationAddresses []netip.Addr, strategy C.NetworkStrategy, interfaceType []C.InterfaceType, fallbackInterfaceType []C.InterfaceType, fallbackDelay time.Duration) (net.PacketConn, netip.Addr, error) {
|
||||
if parallelDialer, isParallel := dialer.(ParallelNetworkDialer); isParallel {
|
||||
return parallelDialer.ListenSerialNetworkPacket(ctx, destination, destinationAddresses, strategy, interfaceType, fallbackInterfaceType, fallbackDelay)
|
||||
}
|
||||
var errors []error
|
||||
if parallelDialer, isParallel := dialer.(ParallelInterfaceDialer); isParallel {
|
||||
for _, address := range destinationAddresses {
|
||||
conn, err := parallelDialer.ListenSerialInterfacePacket(ctx, M.SocksaddrFrom(address, destination.Port), strategy, interfaceType, fallbackInterfaceType, fallbackDelay)
|
||||
if err == nil {
|
||||
return conn, address, nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
}
|
||||
} else {
|
||||
for _, address := range destinationAddresses {
|
||||
conn, err := dialer.ListenPacket(ctx, M.SocksaddrFrom(address, destination.Port))
|
||||
if err == nil {
|
||||
return conn, address, nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
for _, address := range destinationAddresses {
|
||||
conn, err := dialer.ListenSerialInterfacePacket(ctx, M.SocksaddrFrom(address, destination.Port), strategy, interfaceType, fallbackInterfaceType, fallbackDelay)
|
||||
if err == nil {
|
||||
return conn, address, nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
}
|
||||
return nil, netip.Addr{}, E.Errors(errors...)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/control"
|
||||
@@ -123,7 +124,7 @@ func (l *Listener) loopUDPOut() {
|
||||
case packet := <-l.packetOutbound:
|
||||
packet.Buffer.Release()
|
||||
N.PutPacketBuffer(packet)
|
||||
default:
|
||||
case <-time.After(time.Second):
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,10 +41,10 @@ func NewRouterWithOptions(router adapter.ConnectionRouterEx, logger logger.Conte
|
||||
NewStreamContext: func(ctx context.Context, conn net.Conn) context.Context {
|
||||
return log.ContextWithNewID(ctx)
|
||||
},
|
||||
Logger: logger,
|
||||
HandlerEx: adapter.NewRouteContextHandlerEx(router),
|
||||
Padding: options.Padding,
|
||||
Brutal: brutalOptions,
|
||||
Logger: logger,
|
||||
Handler: adapter.NewRouteContextHandler(router, logger),
|
||||
Padding: options.Padding,
|
||||
Brutal: brutalOptions,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -52,7 +52,6 @@ func NewRouterWithOptions(router adapter.ConnectionRouterEx, logger logger.Conte
|
||||
return &Router{router, service}, nil
|
||||
}
|
||||
|
||||
// Deprecated: Use RouteConnectionEx instead.
|
||||
func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
|
||||
if metadata.Destination == mux.Destination {
|
||||
// TODO: check if WithContext is necessary
|
||||
@@ -62,7 +61,6 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated: Use RoutePacketConnectionEx instead.
|
||||
func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
|
||||
return r.router.RoutePacketConnection(ctx, conn, metadata)
|
||||
}
|
||||
|
||||
@@ -97,10 +97,6 @@ func (c *echServerConfig) startWatcher() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = watcher.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.watcher = watcher
|
||||
return nil
|
||||
}
|
||||
@@ -236,7 +232,7 @@ func NewECHServer(ctx context.Context, logger log.Logger, options option.Inbound
|
||||
var echKey []byte
|
||||
if len(options.ECH.Key) > 0 {
|
||||
echKey = []byte(strings.Join(options.ECH.Key, "\n"))
|
||||
} else if options.ECH.KeyPath != "" {
|
||||
} else if options.KeyPath != "" {
|
||||
content, err := os.ReadFile(options.ECH.KeyPath)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "read ECH key")
|
||||
|
||||
@@ -106,10 +106,6 @@ func (c *STDServerConfig) startWatcher() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = watcher.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.watcher = watcher
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ func applyDebugListenOption(options option.DebugOptions) {
|
||||
|
||||
encoder := json.NewEncoder(writer)
|
||||
encoder.SetIndent("", " ")
|
||||
encoder.Encode(&memObject)
|
||||
encoder.Encode(memObject)
|
||||
})
|
||||
r.Route("/pprof", func(r chi.Router) {
|
||||
r.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
|
||||
|
||||
@@ -2,61 +2,6 @@
|
||||
icon: material/alert-decagram
|
||||
---
|
||||
|
||||
#### 1.11.0-alpha.21
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.11.0-alpha.20
|
||||
|
||||
* Add UDP GSO support for WireGuard
|
||||
* Make GSO adaptive **1**
|
||||
|
||||
**1**:
|
||||
|
||||
For WireGuard outbound and endpoint, GSO will be automatically enabled when available,
|
||||
see [WireGuard Outbound](/configuration/outbound/wireguard/#gso).
|
||||
|
||||
For TUN, GSO has been removed,
|
||||
see [Deprecated](/deprecated/#gso-option-in-tun).
|
||||
|
||||
#### 1.11.0-alpha.19
|
||||
|
||||
* Upgrade WireGuard outbound to endpoint **1**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
The new WireGuard endpoint combines inbound and outbound capabilities,
|
||||
and the old outbound will be removed in sing-box 1.13.0.
|
||||
|
||||
See [Endpoint](/configuration/endpoint/), [WireGuard Endpoint](/configuration/endpoint/wireguard/)
|
||||
and [Migrate WireGuard outbound fields to route options](/migration/#migrate-wireguard-outbound-to-endpoint).
|
||||
|
||||
### 1.10.2
|
||||
|
||||
* Add deprecated warnings
|
||||
* Fix proxying websocket connections in HTTP/mixed inbounds
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.11.0-alpha.18
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.11.0-alpha.16
|
||||
|
||||
* Add `cache_capacity` DNS option **1**
|
||||
* Add `override_address` and `override_port` route options **2**
|
||||
* Fixes and improvements
|
||||
|
||||
**1**:
|
||||
|
||||
See [DNS](/configuration/dns/#cache_capacity).
|
||||
|
||||
**2**:
|
||||
|
||||
See [Rule Action](/configuration/route/#override_address) and
|
||||
[Migrate destination override fields to route options](/migration/#migrate-destination-override-fields-to-route-options).
|
||||
|
||||
#### 1.11.0-alpha.15
|
||||
|
||||
* Improve multi network dialing **1**
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
---
|
||||
icon: material/new-box
|
||||
---
|
||||
!!! quote "Changes in sing-box 1.9.0"
|
||||
|
||||
!!! quote "Changes in sing-box 1.11.0"
|
||||
|
||||
:material-plus: [cache_capacity](#cache_capacity)
|
||||
:material-plus: [client_subnet](#client_subnet)
|
||||
|
||||
# DNS
|
||||
|
||||
@@ -20,7 +16,6 @@ icon: material/new-box
|
||||
"disable_cache": false,
|
||||
"disable_expire": false,
|
||||
"independent_cache": false,
|
||||
"cache_capacity": 0,
|
||||
"reverse_mapping": false,
|
||||
"client_subnet": "",
|
||||
"fakeip": {}
|
||||
@@ -63,14 +58,6 @@ Disable dns cache expire.
|
||||
|
||||
Make each DNS server's cache independent for special purposes. If enabled, will slightly degrade performance.
|
||||
|
||||
#### cache_capacity
|
||||
|
||||
!!! question "Since sing-box 1.11.0"
|
||||
|
||||
LRU cache capacity.
|
||||
|
||||
Value less than 1024 will be ignored.
|
||||
|
||||
#### reverse_mapping
|
||||
|
||||
Stores a reverse mapping of IP addresses after responding to a DNS query in order to provide domain names when routing.
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
---
|
||||
icon: material/new-box
|
||||
---
|
||||
!!! quote "sing-box 1.9.0 中的更改"
|
||||
|
||||
!!! quote "sing-box 1.11.0 中的更改"
|
||||
|
||||
:material-plus: [cache_capacity](#cache_capacity)
|
||||
:material-plus: [client_subnet](#client_subnet)
|
||||
|
||||
# DNS
|
||||
|
||||
@@ -20,7 +16,6 @@ icon: material/new-box
|
||||
"disable_cache": false,
|
||||
"disable_expire": false,
|
||||
"independent_cache": false,
|
||||
"cache_capacity": 0,
|
||||
"reverse_mapping": false,
|
||||
"client_subnet": "",
|
||||
"fakeip": {}
|
||||
@@ -62,14 +57,6 @@ icon: material/new-box
|
||||
|
||||
使每个 DNS 服务器的缓存独立,以满足特殊目的。如果启用,将轻微降低性能。
|
||||
|
||||
#### cache_capacity
|
||||
|
||||
!!! question "自 sing-box 1.11.0 起"
|
||||
|
||||
LRU 缓存容量。
|
||||
|
||||
小于 1024 的值将被忽略。
|
||||
|
||||
#### reverse_mapping
|
||||
|
||||
在响应 DNS 查询后存储 IP 地址的反向映射以为路由目的提供域名。
|
||||
|
||||
@@ -379,7 +379,7 @@ Available values: `wifi`, `cellular`, `ethernet` and `other`.
|
||||
|
||||
!!! failure "已在 sing-box 1.10.0 废弃"
|
||||
|
||||
`rule_set_ipcidr_match_source` 已重命名为 `rule_set_ip_cidr_match_source` 且将在 sing-box 1.11.0 中被移除。
|
||||
`rule_set_ipcidr_match_source` 已重命名为 `rule_set_ip_cidr_match_source` 且将在 sing-box 1.11.0 移除。
|
||||
|
||||
使规则集中的 `ip_cidr` 规则匹配源 IP。
|
||||
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
---
|
||||
icon: material/new-box
|
||||
---
|
||||
|
||||
!!! question "Since sing-box 1.11.0"
|
||||
|
||||
# Endpoint
|
||||
|
||||
Endpoint is protocols that has both inbound and outbound behavior.
|
||||
|
||||
### Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"endpoints": [
|
||||
{
|
||||
"type": "",
|
||||
"tag": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
|
||||
| Type | Format |
|
||||
|-------------|---------------------------|
|
||||
| `wireguard` | [WireGuard](./wireguard/) |
|
||||
|
||||
#### tag
|
||||
|
||||
The tag of the endpoint.
|
||||
@@ -1,32 +0,0 @@
|
||||
---
|
||||
icon: material/new-box
|
||||
---
|
||||
|
||||
!!! question "自 sing-box 1.11.0 起"
|
||||
|
||||
# 端点
|
||||
|
||||
端点是具有入站和出站行为的协议。
|
||||
|
||||
### 结构
|
||||
|
||||
```json
|
||||
{
|
||||
"endpoints": [
|
||||
{
|
||||
"type": "",
|
||||
"tag": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 字段
|
||||
|
||||
| 类型 | 格式 |
|
||||
|-------------|---------------------------|
|
||||
| `wireguard` | [WireGuard](./wiregaurd/) |
|
||||
|
||||
#### tag
|
||||
|
||||
端点的标签。
|
||||
@@ -1,133 +0,0 @@
|
||||
---
|
||||
icon: material/new-box
|
||||
---
|
||||
|
||||
!!! question "Since sing-box 1.11.0"
|
||||
|
||||
### Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "wireguard",
|
||||
"tag": "wg-ep",
|
||||
|
||||
"system": false,
|
||||
"name": "",
|
||||
"mtu": 1408,
|
||||
"address": [],
|
||||
"private_key": "",
|
||||
"listen_port": 10000,
|
||||
"peers": [
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"port": 10001,
|
||||
"public_key": "",
|
||||
"pre_shared_key": "",
|
||||
"allowed_ips": [],
|
||||
"persistent_keepalive_interval": 0,
|
||||
"reserved": [0, 0, 0]
|
||||
}
|
||||
],
|
||||
"udp_timeout": "",
|
||||
"workers": 0,
|
||||
|
||||
... // Dial Fields
|
||||
}
|
||||
```
|
||||
|
||||
!!! note ""
|
||||
|
||||
You can ignore the JSON Array [] tag when the content is only one item
|
||||
|
||||
### Fields
|
||||
|
||||
#### system
|
||||
|
||||
Use system interface.
|
||||
|
||||
Requires privilege and cannot conflict with exists system interfaces.
|
||||
|
||||
#### name
|
||||
|
||||
Custom interface name for system interface.
|
||||
|
||||
#### mtu
|
||||
|
||||
WireGuard MTU.
|
||||
|
||||
`1408` will be used by default.
|
||||
|
||||
#### address
|
||||
|
||||
==Required==
|
||||
|
||||
List of IP (v4 or v6) address prefixes to be assigned to the interface.
|
||||
|
||||
#### private_key
|
||||
|
||||
==Required==
|
||||
|
||||
WireGuard requires base64-encoded public and private keys. These can be generated using the wg(8) utility:
|
||||
|
||||
```shell
|
||||
wg genkey
|
||||
echo "private key" || wg pubkey
|
||||
```
|
||||
|
||||
or `sing-box generate wg-keypair`.
|
||||
|
||||
#### peers
|
||||
|
||||
==Required==
|
||||
|
||||
List of WireGuard peers.
|
||||
|
||||
#### peers.address
|
||||
|
||||
WireGuard peer address.
|
||||
|
||||
#### peers.port
|
||||
|
||||
WireGuard peer port.
|
||||
|
||||
#### peers.public_key
|
||||
|
||||
==Required==
|
||||
|
||||
WireGuard peer public key.
|
||||
|
||||
#### peers.pre_shared_key
|
||||
|
||||
WireGuard peer pre-shared key.
|
||||
|
||||
#### peers.allowed_ips
|
||||
|
||||
==Required==
|
||||
|
||||
WireGuard allowed IPs.
|
||||
|
||||
#### peers.persistent_keepalive_interval
|
||||
|
||||
WireGuard persistent keepalive interval, in seconds.
|
||||
|
||||
Disabled by default.
|
||||
|
||||
#### peers.reserved
|
||||
|
||||
WireGuard reserved field bytes.
|
||||
|
||||
#### udp_timeout
|
||||
|
||||
UDP NAT expiration time.
|
||||
|
||||
`5m` will be used by default.
|
||||
|
||||
#### workers
|
||||
|
||||
WireGuard worker count.
|
||||
|
||||
CPU count is used by default.
|
||||
|
||||
### Dial Fields
|
||||
|
||||
See [Dial Fields](/configuration/shared/dial/) for details.
|
||||
@@ -1,135 +0,0 @@
|
||||
---
|
||||
icon: material/new-box
|
||||
---
|
||||
|
||||
!!! question "自 sing-box 1.11.0 起"
|
||||
|
||||
### 结构
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "wireguard",
|
||||
"tag": "wg-ep",
|
||||
|
||||
"system": false,
|
||||
"name": "",
|
||||
"mtu": 1408,
|
||||
"address": [],
|
||||
"private_key": "",
|
||||
"listen_port": 10000,
|
||||
"peers": [
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"port": 10001,
|
||||
"public_key": "",
|
||||
"pre_shared_key": "",
|
||||
"allowed_ips": [],
|
||||
"persistent_keepalive_interval": 0,
|
||||
"reserved": [0, 0, 0]
|
||||
}
|
||||
],
|
||||
"udp_timeout": "",
|
||||
"workers": 0,
|
||||
|
||||
... // 拨号字段
|
||||
}
|
||||
```
|
||||
|
||||
!!! note ""
|
||||
|
||||
当内容只有一项时,可以忽略 JSON 数组 [] 标签
|
||||
|
||||
### 字段
|
||||
|
||||
#### system_interface
|
||||
|
||||
使用系统设备。
|
||||
|
||||
需要特权且不能与已有系统接口冲突。
|
||||
|
||||
#### name
|
||||
|
||||
为系统接口自定义设备名称。
|
||||
|
||||
#### mtu
|
||||
|
||||
WireGuard MTU。
|
||||
|
||||
默认使用 1408。
|
||||
|
||||
#### address
|
||||
|
||||
==必填==
|
||||
|
||||
接口的 IPv4/IPv6 地址或地址段的列表您。
|
||||
|
||||
要分配给接口的 IP(v4 或 v6)地址段列表。
|
||||
|
||||
#### private_key
|
||||
|
||||
==必填==
|
||||
|
||||
WireGuard 需要 base64 编码的公钥和私钥。 这些可以使用 wg(8) 实用程序生成:
|
||||
|
||||
```shell
|
||||
wg genkey
|
||||
echo "private key" || wg pubkey
|
||||
```
|
||||
|
||||
或 `sing-box generate wg-keypair`.
|
||||
|
||||
#### peers
|
||||
|
||||
==必填==
|
||||
|
||||
WireGuard 对等方的列表。
|
||||
|
||||
#### peers.address
|
||||
|
||||
对等方的 IP 地址。
|
||||
|
||||
#### peers.port
|
||||
|
||||
对等方的 WireGuard 端口。
|
||||
|
||||
#### peers.public_key
|
||||
|
||||
==必填==
|
||||
|
||||
对等方的 WireGuard 公钥。
|
||||
|
||||
#### peers.pre_shared_key
|
||||
|
||||
对等方的预共享密钥。
|
||||
|
||||
#### peers.allowed_ips
|
||||
|
||||
==必填==
|
||||
|
||||
对等方的允许 IP 地址。
|
||||
|
||||
#### peers.persistent_keepalive_interval
|
||||
|
||||
对等方的持久性保持活动间隔,以秒为单位。
|
||||
|
||||
默认禁用。
|
||||
|
||||
#### peers.reserved
|
||||
|
||||
对等方的保留字段字节。
|
||||
|
||||
#### udp_timeout
|
||||
|
||||
UDP NAT 过期时间。
|
||||
|
||||
默认使用 `5m`。
|
||||
|
||||
#### workers
|
||||
|
||||
WireGuard worker 数量。
|
||||
|
||||
默认使用 CPU 数量。
|
||||
|
||||
### 拨号字段
|
||||
|
||||
参阅 [拨号字段](/zh/configuration/shared/dial/)。
|
||||
@@ -1,11 +1,7 @@
|
||||
---
|
||||
icon: material/alert-decagram
|
||||
icon: material/new-box
|
||||
---
|
||||
|
||||
!!! quote "Changes in sing-box 1.11.0"
|
||||
|
||||
:material-delete-alert: [gso](#gso)
|
||||
|
||||
!!! quote "Changes in sing-box 1.10.0"
|
||||
|
||||
:material-plus: [address](#address)
|
||||
@@ -50,7 +46,16 @@ icon: material/alert-decagram
|
||||
"172.18.0.1/30",
|
||||
"fdfe:dcba:9876::1/126"
|
||||
],
|
||||
// deprecated
|
||||
"inet4_address": [
|
||||
"172.19.0.1/30"
|
||||
],
|
||||
// deprecated
|
||||
"inet6_address": [
|
||||
"fdfe:dcba:9876::1/126"
|
||||
],
|
||||
"mtu": 9000,
|
||||
"gso": false,
|
||||
"auto_route": true,
|
||||
"iproute2_table_index": 2022,
|
||||
"iproute2_rule_index": 9000,
|
||||
@@ -64,11 +69,28 @@ icon: material/alert-decagram
|
||||
"::/1",
|
||||
"8000::/1"
|
||||
],
|
||||
|
||||
// deprecated
|
||||
"inet4_route_address": [
|
||||
"0.0.0.0/1",
|
||||
"128.0.0.0/1"
|
||||
],
|
||||
// deprecated
|
||||
"inet6_route_address": [
|
||||
"::/1",
|
||||
"8000::/1"
|
||||
],
|
||||
"route_exclude_address": [
|
||||
"192.168.0.0/16",
|
||||
"fc00::/7"
|
||||
],
|
||||
// deprecated
|
||||
"inet4_route_exclude_address": [
|
||||
"192.168.0.0/16"
|
||||
],
|
||||
// deprecated
|
||||
"inet6_route_exclude_address": [
|
||||
"fc00::/7"
|
||||
],
|
||||
"route_address_set": [
|
||||
"geoip-cloudflare"
|
||||
],
|
||||
@@ -115,31 +137,8 @@ icon: material/alert-decagram
|
||||
"match_domain": []
|
||||
}
|
||||
},
|
||||
|
||||
// Deprecated
|
||||
"gso": false,
|
||||
"inet4_address": [
|
||||
"172.19.0.1/30"
|
||||
],
|
||||
"inet6_address": [
|
||||
"fdfe:dcba:9876::1/126"
|
||||
],
|
||||
"inet4_route_address": [
|
||||
"0.0.0.0/1",
|
||||
"128.0.0.0/1"
|
||||
],
|
||||
"inet6_route_address": [
|
||||
"::/1",
|
||||
"8000::/1"
|
||||
],
|
||||
"inet4_route_exclude_address": [
|
||||
"192.168.0.0/16"
|
||||
],
|
||||
"inet6_route_exclude_address": [
|
||||
"fc00::/7"
|
||||
],
|
||||
|
||||
... // Listen Fields
|
||||
...
|
||||
// Listen Fields
|
||||
}
|
||||
```
|
||||
|
||||
@@ -167,7 +166,7 @@ IPv4 and IPv6 prefix for the tun interface.
|
||||
|
||||
!!! failure "Deprecated in sing-box 1.10.0"
|
||||
|
||||
`inet4_address` is merged to `address` and will be removed in sing-box 1.12.0.
|
||||
`inet4_address` is merged to `address` and will be removed in sing-box 1.11.0.
|
||||
|
||||
IPv4 prefix for the tun interface.
|
||||
|
||||
@@ -175,7 +174,7 @@ IPv4 prefix for the tun interface.
|
||||
|
||||
!!! failure "Deprecated in sing-box 1.10.0"
|
||||
|
||||
`inet6_address` is merged to `address` and will be removed in sing-box 1.12.0.
|
||||
`inet6_address` is merged to `address` and will be removed in sing-box 1.11.0.
|
||||
|
||||
IPv6 prefix for the tun interface.
|
||||
|
||||
@@ -185,10 +184,6 @@ The maximum transmission unit.
|
||||
|
||||
#### gso
|
||||
|
||||
!!! failure "Deprecated in sing-box 1.11.0"
|
||||
|
||||
GSO has no advantages for transparent proxy scenarios, is deprecated and no longer works, and will be removed in sing-box 1.12.0.
|
||||
|
||||
!!! question "Since sing-box 1.8.0"
|
||||
|
||||
!!! quote ""
|
||||
@@ -289,7 +284,7 @@ Use custom routes instead of default when `auto_route` is enabled.
|
||||
|
||||
!!! failure "Deprecated in sing-box 1.10.0"
|
||||
|
||||
`inet4_route_address` is deprecated and will be removed in sing-box 1.12.0, please use [route_address](#route_address)
|
||||
`inet4_route_address` is deprecated and will be removed in sing-box 1.11.0, please use [route_address](#route_address)
|
||||
instead.
|
||||
|
||||
Use custom routes instead of default when `auto_route` is enabled.
|
||||
@@ -298,7 +293,7 @@ Use custom routes instead of default when `auto_route` is enabled.
|
||||
|
||||
!!! failure "Deprecated in sing-box 1.10.0"
|
||||
|
||||
`inet6_route_address` is deprecated and will be removed in sing-box 1.12.0, please use [route_address](#route_address)
|
||||
`inet6_route_address` is deprecated and will be removed in sing-box 1.11.0, please use [route_address](#route_address)
|
||||
instead.
|
||||
|
||||
Use custom routes instead of default when `auto_route` is enabled.
|
||||
@@ -313,7 +308,7 @@ Exclude custom routes when `auto_route` is enabled.
|
||||
|
||||
!!! failure "Deprecated in sing-box 1.10.0"
|
||||
|
||||
`inet4_route_exclude_address` is deprecated and will be removed in sing-box 1.12.0, please
|
||||
`inet4_route_exclude_address` is deprecated and will be removed in sing-box 1.11.0, please
|
||||
use [route_exclude_address](#route_exclude_address) instead.
|
||||
|
||||
Exclude custom routes when `auto_route` is enabled.
|
||||
@@ -322,7 +317,7 @@ Exclude custom routes when `auto_route` is enabled.
|
||||
|
||||
!!! failure "Deprecated in sing-box 1.10.0"
|
||||
|
||||
`inet6_route_exclude_address` is deprecated and will be removed in sing-box 1.12.0, please
|
||||
`inet6_route_exclude_address` is deprecated and will be removed in sing-box 1.11.0, please
|
||||
use [route_exclude_address](#route_exclude_address) instead.
|
||||
|
||||
Exclude custom routes when `auto_route` is enabled.
|
||||
@@ -365,9 +360,7 @@ Performance may degrade slightly, so it is not recommended to enable on when it
|
||||
|
||||
#### udp_timeout
|
||||
|
||||
UDP NAT expiration time.
|
||||
|
||||
`5m` will be used by default.
|
||||
UDP NAT expiration time in seconds, default is 300 (5 minutes).
|
||||
|
||||
#### stack
|
||||
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
---
|
||||
icon: material/alert-decagram
|
||||
icon: material/new-box
|
||||
---
|
||||
|
||||
!!! quote "sing-box 1.11.0 中的更改"
|
||||
|
||||
:material-delete-alert: [gso](#gso)
|
||||
|
||||
!!! quote "sing-box 1.10.0 中的更改"
|
||||
!!! quote "Changes in sing-box 1.10.0"
|
||||
|
||||
:material-plus: [address](#address)
|
||||
:material-delete-clock: [inet4_address](#inet4_address)
|
||||
@@ -50,7 +46,16 @@ icon: material/alert-decagram
|
||||
"172.18.0.1/30",
|
||||
"fdfe:dcba:9876::1/126"
|
||||
],
|
||||
// 已弃用
|
||||
"inet4_address": [
|
||||
"172.19.0.1/30"
|
||||
],
|
||||
// 已弃用
|
||||
"inet6_address": [
|
||||
"fdfe:dcba:9876::1/126"
|
||||
],
|
||||
"mtu": 9000,
|
||||
"gso": false,
|
||||
"auto_route": true,
|
||||
"iproute2_table_index": 2022,
|
||||
"iproute2_rule_index": 9000,
|
||||
@@ -64,11 +69,28 @@ icon: material/alert-decagram
|
||||
"::/1",
|
||||
"8000::/1"
|
||||
],
|
||||
|
||||
// 已弃用
|
||||
"inet4_route_address": [
|
||||
"0.0.0.0/1",
|
||||
"128.0.0.0/1"
|
||||
],
|
||||
// 已弃用
|
||||
"inet6_route_address": [
|
||||
"::/1",
|
||||
"8000::/1"
|
||||
],
|
||||
"route_exclude_address": [
|
||||
"192.168.0.0/16",
|
||||
"fc00::/7"
|
||||
],
|
||||
// 已弃用
|
||||
"inet4_route_exclude_address": [
|
||||
"192.168.0.0/16"
|
||||
],
|
||||
// 已弃用
|
||||
"inet6_route_exclude_address": [
|
||||
"fc00::/7"
|
||||
],
|
||||
"route_address_set": [
|
||||
"geoip-cloudflare"
|
||||
],
|
||||
@@ -115,29 +137,6 @@ icon: material/alert-decagram
|
||||
"match_domain": []
|
||||
}
|
||||
},
|
||||
|
||||
// 已弃用
|
||||
"gso": false,
|
||||
"inet4_address": [
|
||||
"172.19.0.1/30"
|
||||
],
|
||||
"inet6_address": [
|
||||
"fdfe:dcba:9876::1/126"
|
||||
],
|
||||
"inet4_route_address": [
|
||||
"0.0.0.0/1",
|
||||
"128.0.0.0/1"
|
||||
],
|
||||
"inet6_route_address": [
|
||||
"::/1",
|
||||
"8000::/1"
|
||||
],
|
||||
"inet4_route_exclude_address": [
|
||||
"192.168.0.0/16"
|
||||
],
|
||||
"inet6_route_exclude_address": [
|
||||
"fc00::/7"
|
||||
],
|
||||
|
||||
... // 监听字段
|
||||
}
|
||||
@@ -169,7 +168,7 @@ tun 接口的 IPv4 和 IPv6 前缀。
|
||||
|
||||
!!! failure "已在 sing-box 1.10.0 废弃"
|
||||
|
||||
`inet4_address` 已合并到 `address` 且将在 sing-box 1.12.0 中被移除。
|
||||
`inet4_address` 已合并到 `address` 且将在 sing-box 1.11.0 移除。
|
||||
|
||||
==必填==
|
||||
|
||||
@@ -179,7 +178,7 @@ tun 接口的 IPv4 前缀。
|
||||
|
||||
!!! failure "已在 sing-box 1.10.0 废弃"
|
||||
|
||||
`inet6_address` 已合并到 `address` 且将在 sing-box 1.12.0 中被移除。
|
||||
`inet6_address` 已合并到 `address` 且将在 sing-box 1.11.0 移除。
|
||||
|
||||
tun 接口的 IPv6 前缀。
|
||||
|
||||
@@ -189,10 +188,6 @@ tun 接口的 IPv6 前缀。
|
||||
|
||||
#### gso
|
||||
|
||||
!!! failure "已在 sing-box 1.11.0 废弃"
|
||||
|
||||
GSO 对于透明代理场景没有优势,已废弃和不再生效,且将在 sing-box 1.12.0 中被移除。
|
||||
|
||||
!!! question "自 sing-box 1.8.0 起"
|
||||
|
||||
!!! quote ""
|
||||
@@ -293,7 +288,7 @@ tun 接口的 IPv6 前缀。
|
||||
|
||||
!!! failure "已在 sing-box 1.10.0 废弃"
|
||||
|
||||
`inet4_route_address` 已合并到 `route_address` 且将在 sing-box 1.12.0 中被移除。
|
||||
`inet4_route_address` 已合并到 `route_address` 且将在 sing-box 1.11.0 移除。
|
||||
|
||||
启用 `auto_route` 时使用自定义路由而不是默认路由。
|
||||
|
||||
@@ -301,7 +296,7 @@ tun 接口的 IPv6 前缀。
|
||||
|
||||
!!! failure "已在 sing-box 1.10.0 废弃"
|
||||
|
||||
`inet6_route_address` 已合并到 `route_address` 且将在 sing-box 1.12.0 中被移除。
|
||||
`inet6_route_address` 已合并到 `route_address` 且将在 sing-box 1.11.0 移除。
|
||||
|
||||
启用 `auto_route` 时使用自定义路由而不是默认路由。
|
||||
|
||||
@@ -315,7 +310,7 @@ tun 接口的 IPv6 前缀。
|
||||
|
||||
!!! failure "已在 sing-box 1.10.0 废弃"
|
||||
|
||||
`inet4_route_exclude_address` 已合并到 `route_exclude_address` 且将在 sing-box 1.12.0 中被移除。
|
||||
`inet4_route_exclude_address` 已合并到 `route_exclude_address` 且将在 sing-box 1.11.0 移除。
|
||||
|
||||
启用 `auto_route` 时排除自定义路由。
|
||||
|
||||
@@ -323,7 +318,7 @@ tun 接口的 IPv6 前缀。
|
||||
|
||||
!!! failure "已在 sing-box 1.10.0 废弃"
|
||||
|
||||
`inet6_route_exclude_address` 已合并到 `route_exclude_address` 且将在 sing-box 1.12.0 中被移除。
|
||||
`inet6_route_exclude_address` 已合并到 `route_exclude_address` 且将在 sing-box 1.11.0 移除。
|
||||
|
||||
启用 `auto_route` 时排除自定义路由。
|
||||
|
||||
@@ -361,9 +356,7 @@ tun 接口的 IPv6 前缀。
|
||||
|
||||
#### udp_timeout
|
||||
|
||||
UDP NAT 过期时间。
|
||||
|
||||
默认使用 `5m`。
|
||||
UDP NAT 过期时间,以秒为单位,默认为 300(5 分钟)。
|
||||
|
||||
#### stack
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ sing-box uses JSON for configuration files.
|
||||
"log": {},
|
||||
"dns": {},
|
||||
"ntp": {},
|
||||
"endpoints": [],
|
||||
"inbounds": [],
|
||||
"outbounds": [],
|
||||
"route": {},
|
||||
@@ -24,7 +23,6 @@ sing-box uses JSON for configuration files.
|
||||
| `log` | [Log](./log/) |
|
||||
| `dns` | [DNS](./dns/) |
|
||||
| `ntp` | [NTP](./ntp/) |
|
||||
| `endpoints` | [Endpoint](./endpoint/) |
|
||||
| `inbounds` | [Inbound](./inbound/) |
|
||||
| `outbounds` | [Outbound](./outbound/) |
|
||||
| `route` | [Route](./route/) |
|
||||
|
||||
@@ -8,7 +8,6 @@ sing-box 使用 JSON 作为配置文件格式。
|
||||
{
|
||||
"log": {},
|
||||
"dns": {},
|
||||
"endpoints": [],
|
||||
"inbounds": [],
|
||||
"outbounds": [],
|
||||
"route": {},
|
||||
@@ -22,7 +21,6 @@ sing-box 使用 JSON 作为配置文件格式。
|
||||
|----------------|------------------------|
|
||||
| `log` | [日志](./log/) |
|
||||
| `dns` | [DNS](./dns/) |
|
||||
| `endpoints` | [端点](./endpoint/) |
|
||||
| `inbounds` | [入站](./inbound/) |
|
||||
| `outbounds` | [出站](./outbound/) |
|
||||
| `route` | [路由](./route/) |
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
---
|
||||
icon: material/alert-decagram
|
||||
---
|
||||
|
||||
!!! quote "Changes in sing-box 1.11.0"
|
||||
|
||||
:material-alert-decagram: [override_address](#override_address)
|
||||
:material-alert-decagram: [override_port](#override_port)
|
||||
|
||||
`direct` outbound send requests directly.
|
||||
|
||||
### Structure
|
||||
@@ -18,6 +9,7 @@ icon: material/alert-decagram
|
||||
|
||||
"override_address": "1.0.0.1",
|
||||
"override_port": 53,
|
||||
"proxy_protocol": 0,
|
||||
|
||||
... // Dial Fields
|
||||
}
|
||||
@@ -27,20 +19,16 @@ icon: material/alert-decagram
|
||||
|
||||
#### override_address
|
||||
|
||||
!!! failure "Deprecated in sing-box 1.11.0"
|
||||
|
||||
Destination override fields are deprecated in sing-box 1.11.0 and will be removed in sing-box 1.13.0, see [Migration](/migration/#migrate-destination-override-fields-to-route-options).
|
||||
|
||||
Override the connection destination address.
|
||||
|
||||
#### override_port
|
||||
|
||||
!!! failure "Deprecated in sing-box 1.11.0"
|
||||
|
||||
Destination override fields are deprecated in sing-box 1.11.0 and will be removed in sing-box 1.13.0, see [Migration](/migration/#migrate-destination-override-fields-to-route-options).
|
||||
|
||||
Override the connection destination port.
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
Write [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header.
|
||||
|
||||
Protocol value can be `1` or `2`.
|
||||
|
||||
### Dial Fields
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
---
|
||||
icon: material/alert-decagram
|
||||
---
|
||||
|
||||
!!! quote "sing-box 1.11.0 中的更改"
|
||||
|
||||
:material-alert-decagram: [override_address](#override_address)
|
||||
:material-alert-decagram: [override_port](#override_port)
|
||||
|
||||
`direct` 出站直接发送请求。
|
||||
|
||||
### 结构
|
||||
@@ -18,6 +9,7 @@ icon: material/alert-decagram
|
||||
|
||||
"override_address": "1.0.0.1",
|
||||
"override_port": 53,
|
||||
"proxy_protocol": 0,
|
||||
|
||||
... // 拨号字段
|
||||
}
|
||||
@@ -27,20 +19,18 @@ icon: material/alert-decagram
|
||||
|
||||
#### override_address
|
||||
|
||||
!!! failure "已在 sing-box 1.11.0 废弃"
|
||||
|
||||
目标覆盖字段在 sing-box 1.11.0 中已废弃,并将在 sing-box 1.13.0 中被移除,参阅 [迁移指南](/migration/#migrate-destination-override-fields-to-route-options)。
|
||||
|
||||
覆盖连接目标地址。
|
||||
|
||||
#### override_port
|
||||
|
||||
!!! failure "已在 sing-box 1.11.0 废弃"
|
||||
|
||||
目标覆盖字段在 sing-box 1.11.0 中已废弃,并将在 sing-box 1.13.0 中被移除,参阅 [迁移指南](/migration/#migrate-destination-override-fields-to-route-options)。
|
||||
|
||||
覆盖连接目标端口。
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
写出 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) 到连接头。
|
||||
|
||||
可用协议版本值:`1` 或 `2`。
|
||||
|
||||
### 拨号字段
|
||||
|
||||
参阅 [拨号字段](/zh/configuration/shared/dial/)。
|
||||
|
||||
@@ -1,15 +1,3 @@
|
||||
---
|
||||
icon: material/delete-clock
|
||||
---
|
||||
|
||||
!!! failure "Deprecated in sing-box 1.11.0"
|
||||
|
||||
WireGuard outbound is deprecated and will be removed in sing-box 1.13.0, check [Migration](/migration/#migrate-wireguard-outbound-to-endpoint).
|
||||
|
||||
!!! quote "Changes in sing-box 1.11.0"
|
||||
|
||||
:material-delete-alert: [gso](#gso)
|
||||
|
||||
!!! quote "Changes in sing-box 1.8.0"
|
||||
|
||||
:material-plus: [gso](#gso)
|
||||
@@ -24,9 +12,10 @@ icon: material/delete-clock
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"system_interface": false,
|
||||
"gso": false,
|
||||
"interface_name": "wg0",
|
||||
"local_address": [
|
||||
"10.0.0.1/32"
|
||||
"10.0.0.2/32"
|
||||
],
|
||||
"private_key": "YNXtAzepDqRv9H52osJVDQnznT5AM11eCK3ESpwSt04=",
|
||||
"peers": [
|
||||
@@ -48,10 +37,6 @@ icon: material/delete-clock
|
||||
"mtu": 1408,
|
||||
"network": "tcp",
|
||||
|
||||
// Deprecated
|
||||
|
||||
"gso": false,
|
||||
|
||||
... // Dial Fields
|
||||
}
|
||||
```
|
||||
@@ -84,10 +69,6 @@ Custom interface name for system interface.
|
||||
|
||||
#### gso
|
||||
|
||||
!!! failure "Deprecated in sing-box 1.11.0"
|
||||
|
||||
GSO will be automatically enabled when available since sing-box 1.11.0.
|
||||
|
||||
!!! question "Since sing-box 1.8.0"
|
||||
|
||||
!!! quote ""
|
||||
|
||||
@@ -1,15 +1,3 @@
|
||||
---
|
||||
icon: material/delete-clock
|
||||
---
|
||||
|
||||
!!! failure "已在 sing-box 1.11.0 废弃"
|
||||
|
||||
WireGuard 出站已被启用,且将在 sing-box 1.13.0 中被移除,参阅 [迁移指南](/migration/#migrate-wireguard-outbound-to-endpoint)。
|
||||
|
||||
!!! quote "sing-box 1.11.0 中的更改"
|
||||
|
||||
:material-delete-alert: [gso](#gso)
|
||||
|
||||
!!! quote "sing-box 1.8.0 中的更改"
|
||||
|
||||
:material-plus: [gso](#gso)
|
||||
@@ -24,9 +12,10 @@ icon: material/delete-clock
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"system_interface": false,
|
||||
"gso": false,
|
||||
"interface_name": "wg0",
|
||||
"local_address": [
|
||||
"10.0.0.1/32"
|
||||
"10.0.0.2/32"
|
||||
],
|
||||
"private_key": "YNXtAzepDqRv9H52osJVDQnznT5AM11eCK3ESpwSt04=",
|
||||
"peer_public_key": "Z1XXLsKYkYxuiYjJIkRvtIKFepCYHTgON+GwPq7SOV4=",
|
||||
@@ -35,10 +24,6 @@ icon: material/delete-clock
|
||||
"workers": 4,
|
||||
"mtu": 1408,
|
||||
"network": "tcp",
|
||||
|
||||
// 废弃的
|
||||
|
||||
"gso": false,
|
||||
|
||||
... // 拨号字段
|
||||
}
|
||||
@@ -72,10 +57,6 @@ icon: material/delete-clock
|
||||
|
||||
#### gso
|
||||
|
||||
!!! failure "已在 sing-box 1.11.0 废弃"
|
||||
|
||||
自 sing-box 1.11.0 起,GSO 将可用时自动启用。
|
||||
|
||||
!!! question "自 sing-box 1.8.0 起"
|
||||
|
||||
!!! quote ""
|
||||
|
||||
@@ -9,7 +9,7 @@ icon: material/new-box
|
||||
:material-plus: [default_network_strategy](#default_network_strategy)
|
||||
:material-plus: [default_network_type](#default_network_type)
|
||||
:material-plus: [default_fallback_network_type](#default_fallback_network_type)
|
||||
:material-plus: [default_fallback_delay](#default_fallback_delay)
|
||||
:material-alert: [default_fallback_delay](#default_fallback_delay)
|
||||
|
||||
!!! quote "Changes in sing-box 1.8.0"
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ icon: material/new-box
|
||||
:material-plus: [network_strategy](#network_strategy)
|
||||
:material-plus: [default_network_type](#default_network_type)
|
||||
:material-plus: [default_fallback_network_type](#default_fallback_network_type)
|
||||
:material-plus: [default_fallback_delay](#default_fallback_delay)
|
||||
:material-alert: [default_fallback_delay](#default_fallback_delay)
|
||||
|
||||
!!! quote "sing-box 1.8.0 中的更改"
|
||||
|
||||
|
||||
@@ -388,7 +388,7 @@ Available values: `wifi`, `cellular`, `ethernet` and `other`.
|
||||
|
||||
!!! failure "已在 sing-box 1.10.0 废弃"
|
||||
|
||||
`rule_set_ipcidr_match_source` 已重命名为 `rule_set_ip_cidr_match_source` 且将在 sing-box 1.11.0 中被移除。
|
||||
`rule_set_ipcidr_match_source` 已重命名为 `rule_set_ip_cidr_match_source` 且将在 sing-box 1.11.0 移除。
|
||||
|
||||
使规则集中的 `ip_cidr` 规则匹配源 IP。
|
||||
|
||||
|
||||
@@ -10,8 +10,12 @@ icon: material/new-box
|
||||
{
|
||||
"action": "route", // default
|
||||
"outbound": "",
|
||||
|
||||
... // route-options Fields
|
||||
"network_strategy": "",
|
||||
"network_type": [],
|
||||
"fallback_network_type": [],
|
||||
"fallback_delay": "",
|
||||
"udp_disable_domain_unmapping": false,
|
||||
"udp_connect": false
|
||||
}
|
||||
```
|
||||
|
||||
@@ -27,34 +31,6 @@ icon: material/new-box
|
||||
|
||||
Tag of target outbound.
|
||||
|
||||
#### route-options Fields
|
||||
|
||||
See `route-options` fields below.
|
||||
|
||||
### route-options
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "route-options",
|
||||
"override_address": "",
|
||||
"override_port": 0,
|
||||
"network_strategy": "",
|
||||
"fallback_delay": "",
|
||||
"udp_disable_domain_unmapping": false,
|
||||
"udp_connect": false
|
||||
}
|
||||
```
|
||||
|
||||
`route-options` set options for routing.
|
||||
|
||||
#### override_address
|
||||
|
||||
Override the connection destination address.
|
||||
|
||||
#### override_port
|
||||
|
||||
Override the connection destination port.
|
||||
|
||||
#### network_strategy
|
||||
|
||||
See [Dial Fields](/configuration/shared/dial/#network_strategy) for details.
|
||||
@@ -86,6 +62,20 @@ do not support receiving UDP packets with domain addresses, such as Surge.
|
||||
|
||||
If enabled, attempts to connect UDP connection to the destination instead of listen.
|
||||
|
||||
### route-options
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "route-options",
|
||||
"network_strategy": "",
|
||||
"fallback_delay": "",
|
||||
"udp_disable_domain_unmapping": false,
|
||||
"udp_connect": false
|
||||
}
|
||||
```
|
||||
|
||||
`route-options` set options for routing.
|
||||
|
||||
### reject
|
||||
|
||||
```json
|
||||
|
||||
@@ -10,8 +10,12 @@ icon: material/new-box
|
||||
{
|
||||
"action": "route", // 默认
|
||||
"outbound": "",
|
||||
|
||||
... // route-options 字段
|
||||
"network_strategy": "",
|
||||
"fallback_delay": "",
|
||||
"network_type": [],
|
||||
"fallback_network_type": [],
|
||||
"udp_disable_domain_unmapping": false,
|
||||
"udp_connect": false
|
||||
}
|
||||
```
|
||||
|
||||
@@ -23,38 +27,6 @@ icon: material/new-box
|
||||
|
||||
目标出站的标签。
|
||||
|
||||
#### route-options 字段
|
||||
|
||||
参阅下方的 `route-options` 字段。
|
||||
|
||||
### route-options
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "route-options",
|
||||
"override_address": "",
|
||||
"override_port": 0,
|
||||
"network_strategy": "",
|
||||
"fallback_delay": "",
|
||||
"udp_disable_domain_unmapping": false,
|
||||
"udp_connect": false
|
||||
}
|
||||
```
|
||||
|
||||
!!! note ""
|
||||
|
||||
当内容只有一项时,可以忽略 JSON 数组 [] 标签
|
||||
|
||||
`route-options` 为路由设置选项。
|
||||
|
||||
#### override_address
|
||||
|
||||
覆盖目标地址。
|
||||
|
||||
#### override_port
|
||||
|
||||
覆盖目标端口。
|
||||
|
||||
#### network_strategy
|
||||
|
||||
详情参阅 [拨号字段](/configuration/shared/dial/#network_strategy)。
|
||||
@@ -84,6 +56,24 @@ icon: material/new-box
|
||||
|
||||
如果启用,将尝试将 UDP 连接 connect 到目标而不是 listen。
|
||||
|
||||
### route-options
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "route-options",
|
||||
"network_strategy": "",
|
||||
"fallback_delay": "",
|
||||
"udp_disable_domain_unmapping": false,
|
||||
"udp_connect": false
|
||||
}
|
||||
```
|
||||
|
||||
!!! note ""
|
||||
|
||||
当内容只有一项时,可以忽略 JSON 数组 [] 标签
|
||||
|
||||
`route-options` 为路由设置选项。
|
||||
|
||||
### reject
|
||||
|
||||
```json
|
||||
|
||||
@@ -68,9 +68,9 @@ Enable UDP fragmentation.
|
||||
|
||||
#### udp_timeout
|
||||
|
||||
UDP NAT expiration time.
|
||||
UDP NAT expiration time in seconds.
|
||||
|
||||
`5m` will be used by default.
|
||||
`5m` is used by default.
|
||||
|
||||
#### detour
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ icon: material/delete-clock
|
||||
|
||||
#### udp_timeout
|
||||
|
||||
UDP NAT 过期时间。
|
||||
UDP NAT 过期时间,以秒为单位。
|
||||
|
||||
默认使用 `5m`。
|
||||
|
||||
|
||||
@@ -22,25 +22,6 @@ check [Migration](../migration/#migrate-legacy-inbound-fields-to-rule-actions).
|
||||
|
||||
Old fields will be removed in sing-box 1.13.0.
|
||||
|
||||
#### Destination override fields in direct outbound
|
||||
|
||||
Destination override fields (`override_address` / `override_port`) in direct outbound are deprecated
|
||||
and can be replaced by rule actions,
|
||||
check [Migration](../migration/#migrate-destination-override-fields-to-route-options).
|
||||
|
||||
#### WireGuard outbound
|
||||
|
||||
WireGuard outbound is deprecated and can be replaced by endpoint,
|
||||
check [Migration](../migration/#migrate-wireguard-outbound-to-endpoint).
|
||||
|
||||
Old outbound will be removed in sing-box 1.13.0.
|
||||
|
||||
#### GSO option in TUN
|
||||
|
||||
GSO has no advantages for transparent proxy scenarios, is deprecated and no longer works in TUN.
|
||||
|
||||
Old fields will be removed in sing-box 1.13.0.
|
||||
|
||||
## 1.10.0
|
||||
|
||||
#### TUN address fields are merged
|
||||
|
||||
@@ -20,26 +20,6 @@ icon: material/delete-alert
|
||||
|
||||
旧字段将在 sing-box 1.13.0 中被移除。
|
||||
|
||||
#### direct 出站中的目标地址覆盖字段
|
||||
|
||||
direct 出站中的目标地址覆盖字段(`override_address` / `override_port`)已废弃且可以通过规则动作替代,
|
||||
参阅 [迁移指南](/migration/#migrate-destination-override-fields-to-route-options)。
|
||||
|
||||
旧字段将在 sing-box 1.13.0 中被移除。
|
||||
|
||||
#### WireGuard 出站
|
||||
|
||||
WireGuard 出站已废弃且可以通过端点替代,
|
||||
参阅 [迁移指南](/migration/#migrate-wireguard-outbound-to-endpoint)。
|
||||
|
||||
旧出站将在 sing-box 1.13.0 中被移除。
|
||||
|
||||
#### TUN 的 GSO 字段
|
||||
|
||||
GSO 对透明代理场景没有优势,已废弃且在 TUN 中不再起作用。
|
||||
|
||||
旧字段将在 sing-box 1.13.0 中被移除。
|
||||
|
||||
## 1.10.0
|
||||
|
||||
#### Match source 规则项已重命名
|
||||
|
||||
@@ -156,115 +156,6 @@ Inbound fields are deprecated and can be replaced by rule actions.
|
||||
}
|
||||
```
|
||||
|
||||
### Migrate destination override fields to route options
|
||||
|
||||
Destination override fields in direct outbound are deprecated and can be replaced by route options.
|
||||
|
||||
!!! info "References"
|
||||
|
||||
[Rule Action](/configuration/route/rule_action/) /
|
||||
[Direct](/configuration/outbound/direct/)
|
||||
|
||||
=== ":material-card-remove: Deprecated"
|
||||
|
||||
```json
|
||||
{
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "direct",
|
||||
"override_address": "1.1.1.1",
|
||||
"override_port": 443
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
=== ":material-card-multiple: New"
|
||||
|
||||
```json
|
||||
{
|
||||
"route": {
|
||||
"rules": [
|
||||
{
|
||||
"action": "route-options", // or route
|
||||
"override_address": "1.1.1.1",
|
||||
"override_port": 443
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Migrate WireGuard outbound to endpoint
|
||||
|
||||
WireGuard outbound is deprecated and can be replaced by endpoint.
|
||||
|
||||
!!! info "References"
|
||||
|
||||
[Endpoint](/configuration/endpoint/) /
|
||||
[WireGuard Endpoint](/configuration/endpoint/wireguard/) /
|
||||
[WireGuard Outbound](/configuration/outbound/wireguard/)
|
||||
|
||||
=== ":material-card-remove: Deprecated"
|
||||
|
||||
```json
|
||||
{
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "wireguard",
|
||||
"tag": "wg-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 10001,
|
||||
"system_interface": true,
|
||||
"gso": true,
|
||||
"interface_name": "wg0",
|
||||
"local_address": [
|
||||
"10.0.0.1/32"
|
||||
],
|
||||
"private_key": "<private_key>",
|
||||
"peer_public_key": "<peer_public_key>",
|
||||
"pre_shared_key": "<pre_shared_key>",
|
||||
"reserved": [0, 0, 0],
|
||||
"mtu": 1408
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
=== ":material-card-multiple: New"
|
||||
|
||||
```json
|
||||
{
|
||||
"endpoints": [
|
||||
{
|
||||
"type": "wireguard",
|
||||
"tag": "wg-ep",
|
||||
"system": true,
|
||||
"name": "wg0",
|
||||
"mtu": 1408,
|
||||
"address": [
|
||||
"10.0.0.2/32"
|
||||
],
|
||||
"private_key": "<private_key>",
|
||||
"listen_port": 10000,
|
||||
"peers": [
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"port": 10001,
|
||||
"public_key": "<peer_public_key>",
|
||||
"pre_shared_key": "<pre_shared_key>",
|
||||
"allowed_ips": [
|
||||
"0.0.0.0/0"
|
||||
],
|
||||
"persistent_keepalive_interval": 30,
|
||||
"reserved": [0, 0, 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 1.10.0
|
||||
|
||||
### TUN address fields are merged
|
||||
|
||||
@@ -156,116 +156,6 @@ icon: material/arrange-bring-forward
|
||||
}
|
||||
```
|
||||
|
||||
### 迁移 direct 出站中的目标地址覆盖字段到路由字段
|
||||
|
||||
direct 出站中的目标地址覆盖字段已废弃,且可以被路由字段替代。
|
||||
|
||||
!!! info "参考"
|
||||
|
||||
[Rule Action](/zh/configuration/route/rule_action/) /
|
||||
[Direct](/zh/configuration/outbound/direct/)
|
||||
|
||||
=== ":material-card-remove: 弃用的"
|
||||
|
||||
```json
|
||||
{
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "direct",
|
||||
"override_address": "1.1.1.1",
|
||||
"override_port": 443
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
=== ":material-card-multiple: 新的"
|
||||
|
||||
```json
|
||||
{
|
||||
"route": {
|
||||
"rules": [
|
||||
{
|
||||
"action": "route-options", // 或 route
|
||||
"override_address": "1.1.1.1",
|
||||
"override_port": 443
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 迁移 WireGuard 出站到端点
|
||||
|
||||
WireGuard 出站已被弃用,且可以被端点替代。
|
||||
|
||||
!!! info "参考"
|
||||
|
||||
[端点](/zh/configuration/endpoint/) /
|
||||
[WireGuard 端点](/zh/configuration/endpoint/wireguard/) /
|
||||
[WireGuard 出站](/zh/configuration/outbound/wireguard/)
|
||||
|
||||
=== ":material-card-remove: 弃用的"
|
||||
|
||||
```json
|
||||
{
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "wireguard",
|
||||
"tag": "wg-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 10001,
|
||||
"system_interface": true,
|
||||
"gso": true,
|
||||
"interface_name": "wg0",
|
||||
"local_address": [
|
||||
"10.0.0.1/32"
|
||||
],
|
||||
"private_key": "<private_key>",
|
||||
"peer_public_key": "<peer_public_key>",
|
||||
"pre_shared_key": "<pre_shared_key>",
|
||||
"reserved": [0, 0, 0],
|
||||
"mtu": 1408
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
=== ":material-card-multiple: 新的"
|
||||
|
||||
```json
|
||||
{
|
||||
"endpoints": [
|
||||
{
|
||||
"type": "wireguard",
|
||||
"tag": "wg-ep",
|
||||
"system": true,
|
||||
"name": "wg0",
|
||||
"mtu": 1408,
|
||||
"address": [
|
||||
"10.0.0.2/32"
|
||||
],
|
||||
"private_key": "<private_key>",
|
||||
"listen_port": 10000,
|
||||
"peers": [
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"port": 10001,
|
||||
"public_key": "<peer_public_key>",
|
||||
"pre_shared_key": "<pre_shared_key>",
|
||||
"allowed_ips": [
|
||||
"0.0.0.0/0"
|
||||
],
|
||||
"persistent_keepalive_interval": 30,
|
||||
"reserved": [0, 0, 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 1.10.0
|
||||
|
||||
### TUN 地址字段已合并
|
||||
@@ -274,6 +164,8 @@ WireGuard 出站已被弃用,且可以被端点替代。
|
||||
`inet4_route_address` 和 `inet6_route_address` 已合并为 `route_address`,
|
||||
`inet4_route_exclude_address` 和 `inet6_route_exclude_address` 已合并为 `route_exclude_address`。
|
||||
|
||||
旧字段已废弃,且将在 sing-box 1.11.0 中移除。
|
||||
|
||||
!!! info "参考"
|
||||
|
||||
[TUN](/zh/configuration/inbound/tun/)
|
||||
|
||||
@@ -33,31 +33,17 @@ func (n Note) Impending() bool {
|
||||
}
|
||||
|
||||
func (n Note) Message() string {
|
||||
if n.MigrationLink != "" {
|
||||
return F.ToString(
|
||||
n.Description, " is deprecated in sing-box ", n.DeprecatedVersion,
|
||||
" and will be removed in sing-box ", n.ScheduledVersion, ", please checkout documentation for migration.",
|
||||
)
|
||||
} else {
|
||||
return F.ToString(
|
||||
n.Description, " is deprecated in sing-box ", n.DeprecatedVersion,
|
||||
" and will be removed in sing-box ", n.ScheduledVersion, ".",
|
||||
)
|
||||
}
|
||||
return F.ToString(
|
||||
n.Description, " is deprecated in sing-box ", n.DeprecatedVersion,
|
||||
" and will be removed in sing-box ", n.ScheduledVersion, ", please checkout documentation for migration.",
|
||||
)
|
||||
}
|
||||
|
||||
func (n Note) MessageWithLink() string {
|
||||
if n.MigrationLink != "" {
|
||||
return F.ToString(
|
||||
n.Description, " is deprecated in sing-box ", n.DeprecatedVersion,
|
||||
" and will be removed in sing-box ", n.ScheduledVersion, ", checkout documentation for migration: ", n.MigrationLink,
|
||||
)
|
||||
} else {
|
||||
return F.ToString(
|
||||
n.Description, " is deprecated in sing-box ", n.DeprecatedVersion,
|
||||
" and will be removed in sing-box ", n.ScheduledVersion, ".",
|
||||
)
|
||||
}
|
||||
return F.ToString(
|
||||
n.Description, " is deprecated in sing-box ", n.DeprecatedVersion,
|
||||
" and will be removed in sing-box ", n.ScheduledVersion, ", checkout documentation for migration: ", n.MigrationLink,
|
||||
)
|
||||
}
|
||||
|
||||
var OptionBadMatchSource = Note{
|
||||
@@ -114,41 +100,6 @@ var OptionInboundOptions = Note{
|
||||
MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-legacy-special-outbounds-to-rule-actions",
|
||||
}
|
||||
|
||||
var OptionDestinationOverrideFields = Note{
|
||||
Name: "destination-override-fields",
|
||||
Description: "destination override fields in direct outbound",
|
||||
DeprecatedVersion: "1.11.0",
|
||||
ScheduledVersion: "1.13.0",
|
||||
EnvName: "DESTINATION_OVERRIDE_FIELDS",
|
||||
MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-destination-override-fields-to-route-options",
|
||||
}
|
||||
|
||||
var OptionWireGuardOutbound = Note{
|
||||
Name: "wireguard-outbound",
|
||||
Description: "legacy wireguard outbound",
|
||||
DeprecatedVersion: "1.11.0",
|
||||
ScheduledVersion: "1.13.0",
|
||||
EnvName: "WIREGUARD_OUTBOUND",
|
||||
MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-wireguard-outbound-to-endpoint",
|
||||
}
|
||||
|
||||
var OptionWireGuardGSO = Note{
|
||||
Name: "wireguard-gso",
|
||||
Description: "GSO option in wireguard outbound",
|
||||
DeprecatedVersion: "1.11.0",
|
||||
ScheduledVersion: "1.13.0",
|
||||
EnvName: "WIREGUARD_GSO",
|
||||
MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-wireguard-outbound-to-endpoint",
|
||||
}
|
||||
|
||||
var OptionTUNGSO = Note{
|
||||
Name: "tun-gso",
|
||||
Description: "GSO option in tun",
|
||||
DeprecatedVersion: "1.11.0",
|
||||
ScheduledVersion: "1.12.0",
|
||||
EnvName: "TUN_GSO",
|
||||
}
|
||||
|
||||
var Options = []Note{
|
||||
OptionBadMatchSource,
|
||||
OptionGEOIP,
|
||||
@@ -156,8 +107,4 @@ var Options = []Note{
|
||||
OptionTUNAddressX,
|
||||
OptionSpecialOutbounds,
|
||||
OptionInboundOptions,
|
||||
OptionDestinationOverrideFields,
|
||||
OptionWireGuardOutbound,
|
||||
OptionWireGuardGSO,
|
||||
OptionTUNGSO,
|
||||
}
|
||||
|
||||
@@ -34,5 +34,5 @@ func (f *stderrManager) ReportDeprecated(feature Note) {
|
||||
return
|
||||
}
|
||||
f.logger.Error(feature.MessageWithLink())
|
||||
f.logger.Fatal("to continuing using this feature, set environment variable ENABLE_DEPRECATED_" + feature.EnvName + "=true")
|
||||
f.logger.Fatal("to continuing using this feature, set ENABLE_DEPRECATED_" + feature.EnvName + "=true")
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ func parseConfig(ctx context.Context, configContent string) (option.Options, err
|
||||
}
|
||||
|
||||
func CheckConfig(configContent string) error {
|
||||
ctx := box.Context(context.Background(), include.InboundRegistry(), include.OutboundRegistry(), include.EndpointRegistry())
|
||||
ctx := box.Context(context.Background(), include.InboundRegistry(), include.OutboundRegistry())
|
||||
options, err := parseConfig(ctx, configContent)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -131,7 +131,7 @@ func (s *platformInterfaceStub) SendNotification(notification *platform.Notifica
|
||||
}
|
||||
|
||||
func FormatConfig(configContent string) (string, error) {
|
||||
options, err := parseConfig(box.Context(context.Background(), include.InboundRegistry(), include.OutboundRegistry(), include.EndpointRegistry()), configContent)
|
||||
options, err := parseConfig(box.Context(context.Background(), include.InboundRegistry(), include.OutboundRegistry()), configContent)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ type BoxService struct {
|
||||
}
|
||||
|
||||
func NewService(configContent string, platformInterface PlatformInterface) (*BoxService, error) {
|
||||
ctx := box.Context(context.Background(), include.InboundRegistry(), include.OutboundRegistry(), include.EndpointRegistry())
|
||||
ctx := box.Context(context.Background(), include.InboundRegistry(), include.OutboundRegistry())
|
||||
ctx = filemanager.WithDefault(ctx, sWorkingPath, sTempPath, sUserID, sGroupID)
|
||||
service.MustRegister[deprecated.Manager](ctx, new(deprecatedManager))
|
||||
options, err := parseConfig(ctx, configContent)
|
||||
|
||||
19
go.mod
19
go.mod
@@ -22,21 +22,21 @@ require (
|
||||
github.com/sagernet/cors v1.2.1
|
||||
github.com/sagernet/fswatch v0.1.1
|
||||
github.com/sagernet/gomobile v0.1.4
|
||||
github.com/sagernet/gvisor v0.0.0-20241123041152-536d05261cff
|
||||
github.com/sagernet/gvisor v0.0.0-20241021032506-a4324256e4a3
|
||||
github.com/sagernet/quic-go v0.48.1-beta.1
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
|
||||
github.com/sagernet/sing v0.6.0-alpha.18
|
||||
github.com/sagernet/sing-dns v0.4.0-alpha.3
|
||||
github.com/sagernet/sing v0.6.0-alpha.9
|
||||
github.com/sagernet/sing-dns v0.4.0-alpha.1
|
||||
github.com/sagernet/sing-mux v0.3.0-alpha.1
|
||||
github.com/sagernet/sing-quic v0.4.0-alpha.4
|
||||
github.com/sagernet/sing-quic v0.3.0-rc.2
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.0
|
||||
github.com/sagernet/sing-shadowtls v0.2.0-alpha.2
|
||||
github.com/sagernet/sing-tun v0.6.0-alpha.14
|
||||
github.com/sagernet/sing-vmess v0.2.0-beta.1
|
||||
github.com/sagernet/sing-shadowtls v0.1.4
|
||||
github.com/sagernet/sing-tun v0.6.0-alpha.8
|
||||
github.com/sagernet/sing-vmess v0.1.12
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7
|
||||
github.com/sagernet/utls v1.6.7
|
||||
github.com/sagernet/wireguard-go v0.0.1-beta.4
|
||||
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8
|
||||
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854
|
||||
github.com/spf13/cobra v1.8.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
@@ -53,8 +53,6 @@ require (
|
||||
howett.net/plist v1.0.1
|
||||
)
|
||||
|
||||
//replace github.com/sagernet/sing => ../sing
|
||||
|
||||
require (
|
||||
github.com/ajg/form v1.5.1 // indirect
|
||||
github.com/andybalholm/brotli v1.0.6 // indirect
|
||||
@@ -92,7 +90,6 @@ require (
|
||||
golang.org/x/text v0.20.0 // indirect
|
||||
golang.org/x/time v0.7.0 // indirect
|
||||
golang.org/x/tools v0.24.0 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
36
go.sum
36
go.sum
@@ -99,8 +99,8 @@ github.com/sagernet/fswatch v0.1.1 h1:YqID+93B7VRfqIH3PArW/XpJv5H4OLEVWDfProGoRQ
|
||||
github.com/sagernet/fswatch v0.1.1/go.mod h1:nz85laH0mkQqJfaOrqPpkwtU1znMFNVTpT/5oRsVz/o=
|
||||
github.com/sagernet/gomobile v0.1.4 h1:WzX9ka+iHdupMgy2Vdich+OAt7TM8C2cZbIbzNjBrJY=
|
||||
github.com/sagernet/gomobile v0.1.4/go.mod h1:Pqq2+ZVvs10U7xK+UwJgwYWUykewi8H6vlslAO73n9E=
|
||||
github.com/sagernet/gvisor v0.0.0-20241123041152-536d05261cff h1:mlohw3360Wg1BNGook/UHnISXhUx4Gd/3tVLs5T0nSs=
|
||||
github.com/sagernet/gvisor v0.0.0-20241123041152-536d05261cff/go.mod h1:ehZwnT2UpmOWAHFL48XdBhnd4Qu4hN2O3Ji0us3ZHMw=
|
||||
github.com/sagernet/gvisor v0.0.0-20241021032506-a4324256e4a3 h1:RxEz7LhPNiF/gX/Hg+OXr5lqsM9iVAgmaK1L1vzlDRM=
|
||||
github.com/sagernet/gvisor v0.0.0-20241021032506-a4324256e4a3/go.mod h1:ehZwnT2UpmOWAHFL48XdBhnd4Qu4hN2O3Ji0us3ZHMw=
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis=
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||
github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I=
|
||||
@@ -110,32 +110,30 @@ github.com/sagernet/quic-go v0.48.1-beta.1/go.mod h1:1WgdDIVD1Gybp40JTWketeSfKA/
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
|
||||
github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
|
||||
github.com/sagernet/sing v0.6.0-alpha.18 h1:ih4CurU8KvbhfagYjSqVrE2LR0oBSXSZTNH2sAGPGiM=
|
||||
github.com/sagernet/sing v0.6.0-alpha.18/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing-dns v0.4.0-alpha.3 h1:TcAQdz68Gs28VD9o9zDIW7IS8A9LZDruTPI9g9JbGHA=
|
||||
github.com/sagernet/sing-dns v0.4.0-alpha.3/go.mod h1:9LHcYKg2bGQpbtXrfNbopz8ok/zBK9ljiI2kmFG9JKg=
|
||||
github.com/sagernet/sing v0.6.0-alpha.9 h1:tOeHdRECQwe9R/1edVHbckF/IBoJoGzqhHRnHsNAQb8=
|
||||
github.com/sagernet/sing v0.6.0-alpha.9/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing-dns v0.4.0-alpha.1 h1:2KlP8DeqtGkULFiZtvG2r7SuoJP6orANFzJwC5vDKvg=
|
||||
github.com/sagernet/sing-dns v0.4.0-alpha.1/go.mod h1:vgHATsm4wdymwpvBZPei8RY+546iGXS6hlWv2x6YKcM=
|
||||
github.com/sagernet/sing-mux v0.3.0-alpha.1 h1:IgNX5bJBpL41gGbp05pdDOvh/b5eUQ6cv9240+Ngipg=
|
||||
github.com/sagernet/sing-mux v0.3.0-alpha.1/go.mod h1:FTcImmdfW38Lz7b+HQ+mxxOth1lz4ao8uEnz+MwIJQE=
|
||||
github.com/sagernet/sing-quic v0.4.0-alpha.4 h1:P9xAx3nIfcqb9M8jfgs0uLm+VxCcaY++FCqaBfHY3dQ=
|
||||
github.com/sagernet/sing-quic v0.4.0-alpha.4/go.mod h1:h5RkKTmUhudJKzK7c87FPXD5w1bJjVyxMN9+opZcctA=
|
||||
github.com/sagernet/sing-quic v0.3.0-rc.2 h1:7vcC4bdS1GBJzHZhfmJiH0CfzQ4mYLUW51Z2RNHcGwc=
|
||||
github.com/sagernet/sing-quic v0.3.0-rc.2/go.mod h1:3UOq51WVqzra7eCgod7t4hqnTaOiZzFUci9avMrtOqs=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wKFHi+8XwgADg=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
|
||||
github.com/sagernet/sing-shadowtls v0.2.0-alpha.2 h1:RPrpgAdkP5td0vLfS5ldvYosFjSsZtRPxiyLV6jyKg0=
|
||||
github.com/sagernet/sing-shadowtls v0.2.0-alpha.2/go.mod h1:0j5XlzKxaWRIEjc1uiSKmVoWb0k+L9QgZVb876+thZA=
|
||||
github.com/sagernet/sing-tun v0.6.0-alpha.14 h1:0nE66HdC6nBSOaUG0CEV5rwB5Te3Gts9buVOPvWrGT4=
|
||||
github.com/sagernet/sing-tun v0.6.0-alpha.14/go.mod h1:xvZlEl1EGBbQeshv4UXmG7hA3f0ngFjpdCIYk308vfg=
|
||||
github.com/sagernet/sing-vmess v0.1.13-0.20241123134803-8b806fd4b087 h1:p92kbwAIm5Is8V+fK6IB61AZs/nfWoyxxJeib2Dh2o0=
|
||||
github.com/sagernet/sing-vmess v0.1.13-0.20241123134803-8b806fd4b087/go.mod h1:fLyE1emIcvQ5DV8reFWnufquZ7MkCSYM5ThodsR9NrQ=
|
||||
github.com/sagernet/sing-vmess v0.2.0-beta.1 h1:5sXQ23uwNlZuDvygzi0dFtnG0Csm/SNqTjAHXJkpuj4=
|
||||
github.com/sagernet/sing-vmess v0.2.0-beta.1/go.mod h1:fLyE1emIcvQ5DV8reFWnufquZ7MkCSYM5ThodsR9NrQ=
|
||||
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
|
||||
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
|
||||
github.com/sagernet/sing-tun v0.6.0-alpha.8 h1:HhXyUvXxtaXgT+IILZMq6kbrAyDbUwbN+Df/XxpL7Vo=
|
||||
github.com/sagernet/sing-tun v0.6.0-alpha.8/go.mod h1:JkgiLLnQUXln1zLGVoJqUwAulJGT0xoiPU4/pYF1fhU=
|
||||
github.com/sagernet/sing-vmess v0.1.12 h1:2gFD8JJb+eTFMoa8FIVMnknEi+vCSfaiTXTfEYAYAPg=
|
||||
github.com/sagernet/sing-vmess v0.1.12/go.mod h1:luTSsfyBGAc9VhtCqwjR+dt1QgqBhuYBCONB/POhF8I=
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ=
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7/go.mod h1:FP9X2xjT/Az1EsG/orYYoC+5MojWnuI7hrffz8fGwwo=
|
||||
github.com/sagernet/utls v1.6.7 h1:Ep3+aJ8FUGGta+II2IEVNUc3EDhaRCZINWkj/LloIA8=
|
||||
github.com/sagernet/utls v1.6.7/go.mod h1:Uua1TKO/FFuAhLr9rkaVnnrTmmiItzDjv1BUb2+ERwM=
|
||||
github.com/sagernet/wireguard-go v0.0.1-beta.4 h1:8uyM5fxfEXdu4RH05uOK+v25i3lTNdCYMPSAUJ14FnI=
|
||||
github.com/sagernet/wireguard-go v0.0.1-beta.4/go.mod h1:jGXij2Gn2wbrWuYNUmmNhf1dwcZtvyAvQoe8Xd8MbUo=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8 h1:R0OMYAScomNAVpTfbHFpxqJpvwuhxSRi+g6z7gZhABs=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8/go.mod h1:K4J7/npM+VAMUeUmTa2JaA02JmyheP0GpRBOUvn3ecc=
|
||||
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc=
|
||||
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854/go.mod h1:LtfoSK3+NG57tvnVEHgcuBW9ujgE8enPSgzgwStwCAA=
|
||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||
@@ -197,8 +195,6 @@ golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
|
||||
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/adapter/endpoint"
|
||||
"github.com/sagernet/sing-box/adapter/inbound"
|
||||
"github.com/sagernet/sing-box/adapter/outbound"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
@@ -83,14 +82,6 @@ func OutboundRegistry() *outbound.Registry {
|
||||
return registry
|
||||
}
|
||||
|
||||
func EndpointRegistry() *endpoint.Registry {
|
||||
registry := endpoint.NewRegistry()
|
||||
|
||||
registerWireGuardEndpoint(registry)
|
||||
|
||||
return registry
|
||||
}
|
||||
|
||||
func registerStubForRemovedInbounds(registry *inbound.Registry) {
|
||||
inbound.Register[option.ShadowsocksInboundOptions](registry, C.TypeShadowsocksR, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksInboundOptions) (adapter.Inbound, error) {
|
||||
return nil, E.New("ShadowsocksR is deprecated and removed in sing-box 1.6.0")
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
package include
|
||||
|
||||
import (
|
||||
"github.com/sagernet/sing-box/adapter/endpoint"
|
||||
"github.com/sagernet/sing-box/adapter/outbound"
|
||||
"github.com/sagernet/sing-box/protocol/wireguard"
|
||||
)
|
||||
@@ -11,7 +10,3 @@ import (
|
||||
func registerWireGuardOutbound(registry *outbound.Registry) {
|
||||
wireguard.RegisterOutbound(registry)
|
||||
}
|
||||
|
||||
func registerWireGuardEndpoint(registry *endpoint.Registry) {
|
||||
wireguard.RegisterEndpoint(registry)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/adapter/endpoint"
|
||||
"github.com/sagernet/sing-box/adapter/outbound"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
@@ -15,13 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func registerWireGuardOutbound(registry *outbound.Registry) {
|
||||
outbound.Register[option.LegacyWireGuardOutboundOptions](registry, C.TypeWireGuard, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.LegacyWireGuardOutboundOptions) (adapter.Outbound, error) {
|
||||
return nil, E.New(`WireGuard is not included in this build, rebuild with -tags with_wireguard`)
|
||||
})
|
||||
}
|
||||
|
||||
func registerWireGuardEndpoint(registry *endpoint.Registry) {
|
||||
endpoint.Register[option.WireGuardEndpointOptions](registry, C.TypeWireGuard, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.WireGuardEndpointOptions) (adapter.Endpoint, error) {
|
||||
outbound.Register[option.WireGuardOutboundOptions](registry, C.TypeWireGuard, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.WireGuardOutboundOptions) (adapter.Outbound, error) {
|
||||
return nil, E.New(`WireGuard is not included in this build, rebuild with -tags with_wireguard`)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -112,9 +112,6 @@ nav:
|
||||
- V2Ray Transport: configuration/shared/v2ray-transport.md
|
||||
- UDP over TCP: configuration/shared/udp-over-tcp.md
|
||||
- TCP Brutal: configuration/shared/tcp-brutal.md
|
||||
- Endpoint:
|
||||
- configuration/endpoint/index.md
|
||||
- WireGuard: configuration/endpoint/wireguard.md
|
||||
- Inbound:
|
||||
- configuration/inbound/index.md
|
||||
- Direct: configuration/inbound/direct.md
|
||||
@@ -244,7 +241,6 @@ plugins:
|
||||
Multiplex: 多路复用
|
||||
V2Ray Transport: V2Ray 传输层
|
||||
|
||||
Endpoint: 端点
|
||||
Inbound: 入站
|
||||
Outbound: 出站
|
||||
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
package option
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/sagernet/sing-box/experimental/deprecated"
|
||||
"github.com/sagernet/sing/common/json"
|
||||
)
|
||||
|
||||
type DirectInboundOptions struct {
|
||||
ListenOptions
|
||||
Network NetworkList `json:"network,omitempty"`
|
||||
@@ -14,25 +7,9 @@ type DirectInboundOptions struct {
|
||||
OverridePort uint16 `json:"override_port,omitempty"`
|
||||
}
|
||||
|
||||
type _DirectOutboundOptions struct {
|
||||
type DirectOutboundOptions struct {
|
||||
DialerOptions
|
||||
// Deprecated: Use Route Action instead
|
||||
OverrideAddress string `json:"override_address,omitempty"`
|
||||
// Deprecated: Use Route Action instead
|
||||
OverridePort uint16 `json:"override_port,omitempty"`
|
||||
// Deprecated: removed
|
||||
ProxyProtocol uint8 `json:"proxy_protocol,omitempty"`
|
||||
}
|
||||
|
||||
type DirectOutboundOptions _DirectOutboundOptions
|
||||
|
||||
func (d *DirectOutboundOptions) UnmarshalJSONContext(ctx context.Context, content []byte) error {
|
||||
err := json.UnmarshalDisallowUnknownFields(content, (*_DirectOutboundOptions)(d))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if d.OverrideAddress != "" || d.OverridePort != 0 {
|
||||
deprecated.Report(ctx, deprecated.OptionDestinationOverrideFields)
|
||||
}
|
||||
return nil
|
||||
OverridePort uint16 `json:"override_port,omitempty"`
|
||||
ProxyProtocol uint8 `json:"proxy_protocol,omitempty"`
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ type DNSClientOptions struct {
|
||||
DisableCache bool `json:"disable_cache,omitempty"`
|
||||
DisableExpire bool `json:"disable_expire,omitempty"`
|
||||
IndependentCache bool `json:"independent_cache,omitempty"`
|
||||
CacheCapacity uint32 `json:"cache_capacity,omitempty"`
|
||||
ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
package option
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/json"
|
||||
"github.com/sagernet/sing/common/json/badjson"
|
||||
"github.com/sagernet/sing/service"
|
||||
)
|
||||
|
||||
type EndpointOptionsRegistry interface {
|
||||
CreateOptions(endpointType string) (any, bool)
|
||||
}
|
||||
|
||||
type _Endpoint struct {
|
||||
Type string `json:"type"`
|
||||
Tag string `json:"tag,omitempty"`
|
||||
Options any `json:"-"`
|
||||
}
|
||||
|
||||
type Endpoint _Endpoint
|
||||
|
||||
func (h *Endpoint) MarshalJSONContext(ctx context.Context) ([]byte, error) {
|
||||
return badjson.MarshallObjectsContext(ctx, (*_Endpoint)(h), h.Options)
|
||||
}
|
||||
|
||||
func (h *Endpoint) UnmarshalJSONContext(ctx context.Context, content []byte) error {
|
||||
err := json.UnmarshalContext(ctx, content, (*_Endpoint)(h))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
registry := service.FromContext[EndpointOptionsRegistry](ctx)
|
||||
if registry == nil {
|
||||
return E.New("missing Endpoint fields registry in context")
|
||||
}
|
||||
options, loaded := registry.CreateOptions(h.Type)
|
||||
if !loaded {
|
||||
return E.New("unknown inbound type: ", h.Type)
|
||||
}
|
||||
err = badjson.UnmarshallExcludedContext(ctx, content, (*_Endpoint)(h), options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
h.Options = options
|
||||
return nil
|
||||
}
|
||||
@@ -28,7 +28,7 @@ func (h *Inbound) MarshalJSONContext(ctx context.Context) ([]byte, error) {
|
||||
}
|
||||
|
||||
func (h *Inbound) UnmarshalJSONContext(ctx context.Context, content []byte) error {
|
||||
err := json.UnmarshalContext(ctx, content, (*_Inbound)(h))
|
||||
err := json.Unmarshal(content, (*_Inbound)(h))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
98
option/inbound_legacy.go
Normal file
98
option/inbound_legacy.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package option
|
||||
|
||||
import (
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/json"
|
||||
"github.com/sagernet/sing/common/json/badjson"
|
||||
)
|
||||
|
||||
type _LegacyInbound struct {
|
||||
Type string `json:"type"`
|
||||
Tag string `json:"tag,omitempty"`
|
||||
TunOptions TunInboundOptions `json:"-"`
|
||||
RedirectOptions RedirectInboundOptions `json:"-"`
|
||||
TProxyOptions TProxyInboundOptions `json:"-"`
|
||||
DirectOptions DirectInboundOptions `json:"-"`
|
||||
SocksOptions SocksInboundOptions `json:"-"`
|
||||
HTTPOptions HTTPMixedInboundOptions `json:"-"`
|
||||
MixedOptions HTTPMixedInboundOptions `json:"-"`
|
||||
ShadowsocksOptions ShadowsocksInboundOptions `json:"-"`
|
||||
VMessOptions VMessInboundOptions `json:"-"`
|
||||
TrojanOptions TrojanInboundOptions `json:"-"`
|
||||
NaiveOptions NaiveInboundOptions `json:"-"`
|
||||
HysteriaOptions HysteriaInboundOptions `json:"-"`
|
||||
ShadowTLSOptions ShadowTLSInboundOptions `json:"-"`
|
||||
VLESSOptions VLESSInboundOptions `json:"-"`
|
||||
TUICOptions TUICInboundOptions `json:"-"`
|
||||
Hysteria2Options Hysteria2InboundOptions `json:"-"`
|
||||
}
|
||||
|
||||
type LegacyInbound _LegacyInbound
|
||||
|
||||
func (h *LegacyInbound) RawOptions() (any, error) {
|
||||
var rawOptionsPtr any
|
||||
switch h.Type {
|
||||
case C.TypeTun:
|
||||
rawOptionsPtr = &h.TunOptions
|
||||
case C.TypeRedirect:
|
||||
rawOptionsPtr = &h.RedirectOptions
|
||||
case C.TypeTProxy:
|
||||
rawOptionsPtr = &h.TProxyOptions
|
||||
case C.TypeDirect:
|
||||
rawOptionsPtr = &h.DirectOptions
|
||||
case C.TypeSOCKS:
|
||||
rawOptionsPtr = &h.SocksOptions
|
||||
case C.TypeHTTP:
|
||||
rawOptionsPtr = &h.HTTPOptions
|
||||
case C.TypeMixed:
|
||||
rawOptionsPtr = &h.MixedOptions
|
||||
case C.TypeShadowsocks:
|
||||
rawOptionsPtr = &h.ShadowsocksOptions
|
||||
case C.TypeVMess:
|
||||
rawOptionsPtr = &h.VMessOptions
|
||||
case C.TypeTrojan:
|
||||
rawOptionsPtr = &h.TrojanOptions
|
||||
case C.TypeNaive:
|
||||
rawOptionsPtr = &h.NaiveOptions
|
||||
case C.TypeHysteria:
|
||||
rawOptionsPtr = &h.HysteriaOptions
|
||||
case C.TypeShadowTLS:
|
||||
rawOptionsPtr = &h.ShadowTLSOptions
|
||||
case C.TypeVLESS:
|
||||
rawOptionsPtr = &h.VLESSOptions
|
||||
case C.TypeTUIC:
|
||||
rawOptionsPtr = &h.TUICOptions
|
||||
case C.TypeHysteria2:
|
||||
rawOptionsPtr = &h.Hysteria2Options
|
||||
case "":
|
||||
return nil, E.New("missing inbound type")
|
||||
default:
|
||||
return nil, E.New("unknown inbound type: ", h.Type)
|
||||
}
|
||||
return rawOptionsPtr, nil
|
||||
}
|
||||
|
||||
func (h LegacyInbound) MarshalJSON() ([]byte, error) {
|
||||
rawOptions, err := h.RawOptions()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return badjson.MarshallObjects((_LegacyInbound)(h), rawOptions)
|
||||
}
|
||||
|
||||
func (h *LegacyInbound) UnmarshalJSON(bytes []byte) error {
|
||||
err := json.Unmarshal(bytes, (*_LegacyInbound)(h))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rawOptions, err := h.RawOptions()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = badjson.UnmarshallExcluded(bytes, (*_LegacyInbound)(h), rawOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -13,11 +13,15 @@ type _Options struct {
|
||||
Log *LogOptions `json:"log,omitempty"`
|
||||
DNS *DNSOptions `json:"dns,omitempty"`
|
||||
NTP *NTPOptions `json:"ntp,omitempty"`
|
||||
Endpoints []Endpoint `json:"endpoints,omitempty"`
|
||||
Inbounds []Inbound `json:"inbounds,omitempty"`
|
||||
Outbounds []Outbound `json:"outbounds,omitempty"`
|
||||
Route *RouteOptions `json:"route,omitempty"`
|
||||
Experimental *ExperimentalOptions `json:"experimental,omitempty"`
|
||||
|
||||
// Deprecated: use Inbounds instead
|
||||
LegacyInbounds []LegacyInbound `json:"-"`
|
||||
// Deprecated: use Outbounds instead
|
||||
LegacyOutbounds []LegacyOutbound `json:"-"`
|
||||
}
|
||||
|
||||
type Options _Options
|
||||
|
||||
@@ -30,7 +30,7 @@ func (h *Outbound) MarshalJSONContext(ctx context.Context) ([]byte, error) {
|
||||
}
|
||||
|
||||
func (h *Outbound) UnmarshalJSONContext(ctx context.Context, content []byte) error {
|
||||
err := json.UnmarshalContext(ctx, content, (*_Outbound)(h))
|
||||
err := json.Unmarshal(content, (*_Outbound)(h))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
103
option/outbound_legacy.go
Normal file
103
option/outbound_legacy.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package option
|
||||
|
||||
import (
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/json"
|
||||
"github.com/sagernet/sing/common/json/badjson"
|
||||
)
|
||||
|
||||
type _LegacyOutbound struct {
|
||||
Type string `json:"type"`
|
||||
Tag string `json:"tag,omitempty"`
|
||||
DirectOptions DirectOutboundOptions `json:"-"`
|
||||
SocksOptions SOCKSOutboundOptions `json:"-"`
|
||||
HTTPOptions HTTPOutboundOptions `json:"-"`
|
||||
ShadowsocksOptions ShadowsocksOutboundOptions `json:"-"`
|
||||
VMessOptions VMessOutboundOptions `json:"-"`
|
||||
TrojanOptions TrojanOutboundOptions `json:"-"`
|
||||
WireGuardOptions WireGuardOutboundOptions `json:"-"`
|
||||
HysteriaOptions HysteriaOutboundOptions `json:"-"`
|
||||
TorOptions TorOutboundOptions `json:"-"`
|
||||
SSHOptions SSHOutboundOptions `json:"-"`
|
||||
ShadowTLSOptions ShadowTLSOutboundOptions `json:"-"`
|
||||
ShadowsocksROptions ShadowsocksROutboundOptions `json:"-"`
|
||||
VLESSOptions VLESSOutboundOptions `json:"-"`
|
||||
TUICOptions TUICOutboundOptions `json:"-"`
|
||||
Hysteria2Options Hysteria2OutboundOptions `json:"-"`
|
||||
SelectorOptions SelectorOutboundOptions `json:"-"`
|
||||
URLTestOptions URLTestOutboundOptions `json:"-"`
|
||||
}
|
||||
|
||||
type LegacyOutbound _LegacyOutbound
|
||||
|
||||
func (h *LegacyOutbound) RawOptions() (any, error) {
|
||||
var rawOptionsPtr any
|
||||
switch h.Type {
|
||||
case C.TypeDirect:
|
||||
rawOptionsPtr = &h.DirectOptions
|
||||
case C.TypeBlock, C.TypeDNS:
|
||||
rawOptionsPtr = new(StubOptions)
|
||||
case C.TypeSOCKS:
|
||||
rawOptionsPtr = &h.SocksOptions
|
||||
case C.TypeHTTP:
|
||||
rawOptionsPtr = &h.HTTPOptions
|
||||
case C.TypeShadowsocks:
|
||||
rawOptionsPtr = &h.ShadowsocksOptions
|
||||
case C.TypeVMess:
|
||||
rawOptionsPtr = &h.VMessOptions
|
||||
case C.TypeTrojan:
|
||||
rawOptionsPtr = &h.TrojanOptions
|
||||
case C.TypeWireGuard:
|
||||
rawOptionsPtr = &h.WireGuardOptions
|
||||
case C.TypeHysteria:
|
||||
rawOptionsPtr = &h.HysteriaOptions
|
||||
case C.TypeTor:
|
||||
rawOptionsPtr = &h.TorOptions
|
||||
case C.TypeSSH:
|
||||
rawOptionsPtr = &h.SSHOptions
|
||||
case C.TypeShadowTLS:
|
||||
rawOptionsPtr = &h.ShadowTLSOptions
|
||||
case C.TypeShadowsocksR:
|
||||
rawOptionsPtr = &h.ShadowsocksROptions
|
||||
case C.TypeVLESS:
|
||||
rawOptionsPtr = &h.VLESSOptions
|
||||
case C.TypeTUIC:
|
||||
rawOptionsPtr = &h.TUICOptions
|
||||
case C.TypeHysteria2:
|
||||
rawOptionsPtr = &h.Hysteria2Options
|
||||
case C.TypeSelector:
|
||||
rawOptionsPtr = &h.SelectorOptions
|
||||
case C.TypeURLTest:
|
||||
rawOptionsPtr = &h.URLTestOptions
|
||||
case "":
|
||||
return nil, E.New("missing outbound type")
|
||||
default:
|
||||
return nil, E.New("unknown outbound type: ", h.Type)
|
||||
}
|
||||
return rawOptionsPtr, nil
|
||||
}
|
||||
|
||||
func (h *LegacyOutbound) MarshalJSON() ([]byte, error) {
|
||||
rawOptions, err := h.RawOptions()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return badjson.MarshallObjects((*_LegacyOutbound)(h), rawOptions)
|
||||
}
|
||||
|
||||
func (h *LegacyOutbound) UnmarshalJSON(bytes []byte) error {
|
||||
err := json.Unmarshal(bytes, (*_LegacyOutbound)(h))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rawOptions, err := h.RawOptions()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = badjson.UnmarshallExcluded(bytes, (*_LegacyOutbound)(h), rawOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -137,25 +137,24 @@ func (r *DNSRuleAction) UnmarshalJSONContext(ctx context.Context, data []byte) e
|
||||
}
|
||||
|
||||
type RouteActionOptions struct {
|
||||
Outbound string `json:"outbound,omitempty"`
|
||||
RawRouteOptionsActionOptions
|
||||
Outbound string `json:"outbound,omitempty"`
|
||||
NetworkStrategy NetworkStrategy `json:"network_strategy,omitempty"`
|
||||
FallbackDelay uint32 `json:"fallback_delay,omitempty"`
|
||||
UDPDisableDomainUnmapping bool `json:"udp_disable_domain_unmapping,omitempty"`
|
||||
UDPConnect bool `json:"udp_connect,omitempty"`
|
||||
}
|
||||
|
||||
type RawRouteOptionsActionOptions struct {
|
||||
OverrideAddress string `json:"override_address,omitempty"`
|
||||
OverridePort uint16 `json:"override_port,omitempty"`
|
||||
|
||||
NetworkStrategy NetworkStrategy `json:"network_strategy,omitempty"`
|
||||
FallbackDelay uint32 `json:"fallback_delay,omitempty"`
|
||||
|
||||
UDPDisableDomainUnmapping bool `json:"udp_disable_domain_unmapping,omitempty"`
|
||||
UDPConnect bool `json:"udp_connect,omitempty"`
|
||||
type _RouteOptionsActionOptions struct {
|
||||
NetworkStrategy NetworkStrategy `json:"network_strategy,omitempty"`
|
||||
FallbackDelay uint32 `json:"fallback_delay,omitempty"`
|
||||
UDPDisableDomainUnmapping bool `json:"udp_disable_domain_unmapping,omitempty"`
|
||||
UDPConnect bool `json:"udp_connect,omitempty"`
|
||||
}
|
||||
|
||||
type RouteOptionsActionOptions RawRouteOptionsActionOptions
|
||||
type RouteOptionsActionOptions _RouteOptionsActionOptions
|
||||
|
||||
func (r *RouteOptionsActionOptions) UnmarshalJSON(data []byte) error {
|
||||
err := json.Unmarshal(data, (*RawRouteOptionsActionOptions)(r))
|
||||
err := json.Unmarshal(data, (*_RouteOptionsActionOptions)(r))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ func (r DefaultDNSRule) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
|
||||
func (r *DefaultDNSRule) UnmarshalJSONContext(ctx context.Context, data []byte) error {
|
||||
err := json.UnmarshalContext(ctx, data, &r.RawDefaultDNSRule)
|
||||
err := json.Unmarshal(data, &r.RawDefaultDNSRule)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -146,7 +146,7 @@ type LogicalDNSRule struct {
|
||||
DNSRuleAction
|
||||
}
|
||||
|
||||
func (r LogicalDNSRule) MarshalJSON() ([]byte, error) {
|
||||
func (r *LogicalDNSRule) MarshalJSON() ([]byte, error) {
|
||||
return badjson.MarshallObjects(r.RawLogicalDNSRule, r.DNSRuleAction)
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
type TunInboundOptions struct {
|
||||
InterfaceName string `json:"interface_name,omitempty"`
|
||||
MTU uint32 `json:"mtu,omitempty"`
|
||||
GSO bool `json:"gso,omitempty"`
|
||||
Address badoption.Listable[netip.Prefix] `json:"address,omitempty"`
|
||||
AutoRoute bool `json:"auto_route,omitempty"`
|
||||
IPRoute2TableIndex int `json:"iproute2_table_index,omitempty"`
|
||||
@@ -34,13 +35,12 @@ type TunInboundOptions struct {
|
||||
IncludeAndroidUser badoption.Listable[int] `json:"include_android_user,omitempty"`
|
||||
IncludePackage badoption.Listable[string] `json:"include_package,omitempty"`
|
||||
ExcludePackage badoption.Listable[string] `json:"exclude_package,omitempty"`
|
||||
EndpointIndependentNat bool `json:"endpoint_independent_nat,omitempty"`
|
||||
UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"`
|
||||
Stack string `json:"stack,omitempty"`
|
||||
Platform *TunPlatformOptions `json:"platform,omitempty"`
|
||||
InboundOptions
|
||||
|
||||
// Deprecated: removed
|
||||
GSO bool `json:"gso,omitempty"`
|
||||
// Deprecated: merged to Address
|
||||
Inet4Address badoption.Listable[netip.Prefix] `json:"inet4_address,omitempty"`
|
||||
// Deprecated: merged to Address
|
||||
@@ -53,8 +53,6 @@ type TunInboundOptions struct {
|
||||
Inet4RouteExcludeAddress badoption.Listable[netip.Prefix] `json:"inet4_route_exclude_address,omitempty"`
|
||||
// Deprecated: merged to RouteExcludeAddress
|
||||
Inet6RouteExcludeAddress badoption.Listable[netip.Prefix] `json:"inet6_route_exclude_address,omitempty"`
|
||||
// Deprecated: removed
|
||||
EndpointIndependentNat bool `json:"endpoint_independent_nat,omitempty"`
|
||||
}
|
||||
|
||||
type FwMark uint32
|
||||
|
||||
@@ -6,37 +6,14 @@ import (
|
||||
"github.com/sagernet/sing/common/json/badoption"
|
||||
)
|
||||
|
||||
type WireGuardEndpointOptions struct {
|
||||
System bool `json:"system,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
MTU uint32 `json:"mtu,omitempty"`
|
||||
Address badoption.Listable[netip.Prefix] `json:"address"`
|
||||
PrivateKey string `json:"private_key"`
|
||||
ListenPort uint16 `json:"listen_port,omitempty"`
|
||||
Peers []WireGuardPeer `json:"peers,omitempty"`
|
||||
UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"`
|
||||
Workers int `json:"workers,omitempty"`
|
||||
DialerOptions
|
||||
}
|
||||
|
||||
type WireGuardPeer struct {
|
||||
Address string `json:"address,omitempty"`
|
||||
Port uint16 `json:"port,omitempty"`
|
||||
PublicKey string `json:"public_key,omitempty"`
|
||||
PreSharedKey string `json:"pre_shared_key,omitempty"`
|
||||
AllowedIPs badoption.Listable[netip.Prefix] `json:"allowed_ips,omitempty"`
|
||||
PersistentKeepaliveInterval uint16 `json:"persistent_keepalive_interval,omitempty"`
|
||||
Reserved []uint8 `json:"reserved,omitempty"`
|
||||
}
|
||||
|
||||
type LegacyWireGuardOutboundOptions struct {
|
||||
type WireGuardOutboundOptions struct {
|
||||
DialerOptions
|
||||
SystemInterface bool `json:"system_interface,omitempty"`
|
||||
GSO bool `json:"gso,omitempty"`
|
||||
InterfaceName string `json:"interface_name,omitempty"`
|
||||
LocalAddress badoption.Listable[netip.Prefix] `json:"local_address"`
|
||||
PrivateKey string `json:"private_key"`
|
||||
Peers []LegacyWireGuardPeer `json:"peers,omitempty"`
|
||||
Peers []WireGuardPeer `json:"peers,omitempty"`
|
||||
ServerOptions
|
||||
PeerPublicKey string `json:"peer_public_key"`
|
||||
PreSharedKey string `json:"pre_shared_key,omitempty"`
|
||||
@@ -46,10 +23,10 @@ type LegacyWireGuardOutboundOptions struct {
|
||||
Network NetworkList `json:"network,omitempty"`
|
||||
}
|
||||
|
||||
type LegacyWireGuardPeer struct {
|
||||
type WireGuardPeer struct {
|
||||
ServerOptions
|
||||
PublicKey string `json:"public_key,omitempty"`
|
||||
PreSharedKey string `json:"pre_shared_key,omitempty"`
|
||||
AllowedIPs badoption.Listable[netip.Prefix] `json:"allowed_ips,omitempty"`
|
||||
Reserved []uint8 `json:"reserved,omitempty"`
|
||||
PublicKey string `json:"public_key,omitempty"`
|
||||
PreSharedKey string `json:"pre_shared_key,omitempty"`
|
||||
AllowedIPs badoption.Listable[string] `json:"allowed_ips,omitempty"`
|
||||
Reserved []uint8 `json:"reserved,omitempty"`
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ type Outbound struct {
|
||||
|
||||
func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, _ option.StubOptions) (adapter.Outbound, error) {
|
||||
return &Outbound{
|
||||
Adapter: outbound.NewAdapter(C.TypeBlock, tag, []string{N.NetworkTCP, N.NetworkUDP}, nil),
|
||||
Adapter: outbound.NewAdapter(C.TypeBlock, []string{N.NetworkTCP, N.NetworkUDP}, tag, nil),
|
||||
logger: logger,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -68,10 +68,7 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (i *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
func (i *Inbound) Start() error {
|
||||
return i.listener.Start()
|
||||
}
|
||||
|
||||
@@ -79,24 +76,7 @@ func (i *Inbound) Close() error {
|
||||
return i.listener.Close()
|
||||
}
|
||||
|
||||
func (i *Inbound) NewPacketEx(buffer *buf.Buffer, source M.Socksaddr) {
|
||||
var destination M.Socksaddr
|
||||
switch i.overrideOption {
|
||||
case 1:
|
||||
destination = i.overrideDestination
|
||||
case 2:
|
||||
destination = i.overrideDestination
|
||||
destination.Port = i.listener.UDPAddr().Port
|
||||
case 3:
|
||||
destination = source
|
||||
destination.Port = i.overrideDestination.Port
|
||||
}
|
||||
i.udpNat.NewPacket([][]byte{buffer.Bytes()}, source, destination, nil)
|
||||
}
|
||||
|
||||
func (i *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||
metadata.Inbound = i.Tag()
|
||||
metadata.InboundType = i.Type()
|
||||
func (i *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
|
||||
switch i.overrideOption {
|
||||
case 1:
|
||||
metadata.Destination = i.overrideDestination
|
||||
@@ -108,6 +88,28 @@ func (i *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata a
|
||||
metadata.Destination.Port = i.overrideDestination.Port
|
||||
}
|
||||
i.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
|
||||
return i.router.RouteConnection(ctx, conn, metadata)
|
||||
}
|
||||
|
||||
func (i *Inbound) NewPacketEx(buffer *buf.Buffer, source M.Socksaddr) {
|
||||
var destination M.Socksaddr
|
||||
switch i.overrideOption {
|
||||
case 1:
|
||||
destination = i.overrideDestination
|
||||
case 2:
|
||||
destination = i.overrideDestination
|
||||
destination.Port = source.Port
|
||||
case 3:
|
||||
destination = source
|
||||
destination.Port = i.overrideDestination.Port
|
||||
}
|
||||
i.udpNat.NewPacket([][]byte{buffer.Bytes()}, source, destination, nil)
|
||||
}
|
||||
|
||||
func (i *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||
i.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
|
||||
metadata.Inbound = i.Tag()
|
||||
metadata.InboundType = i.Type()
|
||||
i.router.RouteConnectionEx(ctx, conn, metadata, onClose)
|
||||
}
|
||||
|
||||
@@ -117,10 +119,6 @@ func (i *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn,
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = i.Tag()
|
||||
metadata.InboundType = i.Type()
|
||||
//nolint:staticcheck
|
||||
metadata.InboundDetour = i.listener.ListenOptions().Detour
|
||||
//nolint:staticcheck
|
||||
metadata.InboundOptions = i.listener.ListenOptions().InboundOptions
|
||||
metadata.Source = source
|
||||
metadata.Destination = destination
|
||||
metadata.OriginDestination = i.listener.UDPAddr()
|
||||
|
||||
@@ -52,7 +52,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
outbound := &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeDirect, tag, []string{N.NetworkTCP, N.NetworkUDP}, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeDirect, []string{N.NetworkTCP, N.NetworkUDP}, tag, options.DialerOptions),
|
||||
logger: logger,
|
||||
domainStrategy: dns.DomainStrategy(options.DomainStrategy),
|
||||
fallbackDelay: time.Duration(options.FallbackDelay),
|
||||
@@ -63,11 +63,9 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
dialer: outboundDialer,
|
||||
// loopBack: newLoopBackDetector(router),
|
||||
}
|
||||
//nolint:staticcheck
|
||||
if options.ProxyProtocol != 0 {
|
||||
return nil, E.New("Proxy Protocol is deprecated and removed in sing-box 1.6.0")
|
||||
}
|
||||
//nolint:staticcheck
|
||||
if options.OverrideAddress != "" && options.OverridePort != 0 {
|
||||
outbound.overrideOption = 1
|
||||
outbound.overrideDestination = M.ParseSocksaddrHostPort(options.OverrideAddress, options.OverridePort)
|
||||
@@ -163,7 +161,6 @@ func (h *Outbound) DialParallel(ctx context.Context, network string, destination
|
||||
if h.domainStrategy != dns.DomainStrategyAsIS {
|
||||
domainStrategy = h.domainStrategy
|
||||
} else {
|
||||
//nolint:staticcheck
|
||||
domainStrategy = dns.DomainStrategy(metadata.InboundOptions.DomainStrategy)
|
||||
}
|
||||
switch domainStrategy {
|
||||
@@ -203,7 +200,6 @@ func (h *Outbound) DialParallelNetwork(ctx context.Context, network string, dest
|
||||
if h.domainStrategy != dns.DomainStrategyAsIS {
|
||||
domainStrategy = h.domainStrategy
|
||||
} else {
|
||||
//nolint:staticcheck
|
||||
domainStrategy = dns.DomainStrategy(metadata.InboundOptions.DomainStrategy)
|
||||
}
|
||||
switch domainStrategy {
|
||||
|
||||
@@ -28,7 +28,7 @@ type Outbound struct {
|
||||
|
||||
func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.StubOptions) (adapter.Outbound, error) {
|
||||
return &Outbound{
|
||||
Adapter: outbound.NewAdapter(C.TypeDNS, tag, []string{N.NetworkTCP, N.NetworkUDP}, nil),
|
||||
Adapter: outbound.NewAdapter(C.TypeDNS, []string{N.NetworkTCP, N.NetworkUDP}, tag, nil),
|
||||
router: router,
|
||||
logger: logger,
|
||||
}, nil
|
||||
|
||||
@@ -38,7 +38,7 @@ type Selector struct {
|
||||
|
||||
func NewSelector(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.SelectorOutboundOptions) (adapter.Outbound, error) {
|
||||
outbound := &Selector{
|
||||
Adapter: outbound.NewAdapter(C.TypeSelector, tag, nil, options.Outbounds),
|
||||
Adapter: outbound.NewAdapter(C.TypeSelector, nil, tag, options.Outbounds),
|
||||
ctx: ctx,
|
||||
outboundManager: service.FromContext[adapter.OutboundManager](ctx),
|
||||
logger: logger,
|
||||
|
||||
@@ -49,7 +49,7 @@ type URLTest struct {
|
||||
|
||||
func NewURLTest(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.URLTestOutboundOptions) (adapter.Outbound, error) {
|
||||
outbound := &URLTest{
|
||||
Adapter: outbound.NewAdapter(C.TypeURLTest, tag, []string{N.NetworkTCP, N.NetworkUDP}, options.Outbounds),
|
||||
Adapter: outbound.NewAdapter(C.TypeURLTest, []string{N.NetworkTCP, N.NetworkUDP}, tag, options.Outbounds),
|
||||
ctx: ctx,
|
||||
router: router,
|
||||
outboundManager: service.FromContext[adapter.OutboundManager](ctx),
|
||||
|
||||
@@ -61,10 +61,7 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
func (h *Inbound) Start() error {
|
||||
if h.tlsConfig != nil {
|
||||
err := h.tlsConfig.Start()
|
||||
if err != nil {
|
||||
@@ -76,31 +73,31 @@ func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
|
||||
func (h *Inbound) Close() error {
|
||||
return common.Close(
|
||||
h.listener,
|
||||
&h.listener,
|
||||
h.tlsConfig,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||
var err error
|
||||
if h.tlsConfig != nil {
|
||||
conn, err = tls.ServerHandshake(ctx, conn, h.tlsConfig)
|
||||
if err != nil {
|
||||
N.CloseOnHandshakeFailure(conn, onClose, err)
|
||||
h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source, ": TLS handshake"))
|
||||
return
|
||||
}
|
||||
}
|
||||
err = http.HandleConnectionEx(ctx, conn, std_bufio.NewReader(conn), h.authenticator, nil, adapter.NewUpstreamHandlerEx(metadata, h.newUserConnection, h.streamUserPacketConnection), metadata.Source, onClose)
|
||||
err := h.newConnection(ctx, conn, metadata, onClose)
|
||||
N.CloseOnHandshakeFailure(conn, onClose, err)
|
||||
if err != nil {
|
||||
N.CloseOnHandshakeFailure(conn, onClose, err)
|
||||
h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Inbound) newConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) error {
|
||||
var err error
|
||||
if h.tlsConfig != nil {
|
||||
conn, err = tls.ServerHandshake(ctx, conn, h.tlsConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return http.HandleConnectionEx(ctx, conn, std_bufio.NewReader(conn), h.authenticator, nil, adapter.NewUpstreamHandlerEx(metadata, h.newUserConnection, h.streamUserPacketConnection), metadata.Source, onClose)
|
||||
}
|
||||
|
||||
func (h *Inbound) newUserConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||
metadata.Inbound = h.Tag()
|
||||
metadata.InboundType = h.Type()
|
||||
user, loaded := auth.UserFromContext[string](ctx)
|
||||
if !loaded {
|
||||
h.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
|
||||
@@ -113,8 +110,6 @@ func (h *Inbound) newUserConnection(ctx context.Context, conn net.Conn, metadata
|
||||
}
|
||||
|
||||
func (h *Inbound) streamUserPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||
metadata.Inbound = h.Tag()
|
||||
metadata.InboundType = h.Type()
|
||||
user, loaded := auth.UserFromContext[string](ctx)
|
||||
if !loaded {
|
||||
h.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
|
||||
|
||||
@@ -39,7 +39,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
return &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeHTTP, tag, []string{N.NetworkTCP}, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeHTTP, []string{N.NetworkTCP}, tag, options.DialerOptions),
|
||||
logger: logger,
|
||||
client: sHTTP.NewClient(sHTTP.Options{
|
||||
Dialer: detour,
|
||||
|
||||
@@ -17,7 +17,6 @@ import (
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/auth"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
@@ -66,7 +65,7 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
}
|
||||
if len(options.Down) > 0 {
|
||||
receiveBps, err = humanize.ParseBytes(options.Down)
|
||||
if err != nil {
|
||||
if receiveBps == 0 {
|
||||
return nil, E.New("invalid down speed format: ", options.Down)
|
||||
}
|
||||
} else {
|
||||
@@ -86,7 +85,7 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
XPlusPassword: options.Obfs,
|
||||
TLSConfig: tlsConfig,
|
||||
UDPTimeout: udpTimeout,
|
||||
Handler: inbound,
|
||||
Handler: adapter.NewUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, nil),
|
||||
|
||||
// Legacy options
|
||||
|
||||
@@ -118,18 +117,12 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
|
||||
func (h *Inbound) newConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
|
||||
ctx = log.ContextWithNewID(ctx)
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = h.Tag()
|
||||
metadata.InboundType = h.Type()
|
||||
//nolint:staticcheck
|
||||
metadata.InboundDetour = h.listener.ListenOptions().Detour
|
||||
//nolint:staticcheck
|
||||
metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
|
||||
metadata.OriginDestination = h.listener.UDPAddr()
|
||||
metadata.Source = source
|
||||
metadata.Destination = destination
|
||||
h.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
|
||||
userID, _ := auth.UserFromContext[int](ctx)
|
||||
if userName := h.userNameList[userID]; userName != "" {
|
||||
@@ -138,21 +131,16 @@ func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, source M.S
|
||||
} else {
|
||||
h.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
|
||||
}
|
||||
h.router.RouteConnectionEx(ctx, conn, metadata, onClose)
|
||||
return h.router.RouteConnection(ctx, conn, metadata)
|
||||
}
|
||||
|
||||
func (h *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
|
||||
func (h *Inbound) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
|
||||
ctx = log.ContextWithNewID(ctx)
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = h.Tag()
|
||||
metadata.InboundType = h.Type()
|
||||
//nolint:staticcheck
|
||||
metadata.InboundDetour = h.listener.ListenOptions().Detour
|
||||
//nolint:staticcheck
|
||||
metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
|
||||
metadata.OriginDestination = h.listener.UDPAddr()
|
||||
metadata.Source = source
|
||||
metadata.Destination = destination
|
||||
h.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source)
|
||||
userID, _ := auth.UserFromContext[int](ctx)
|
||||
if userName := h.userNameList[userID]; userName != "" {
|
||||
@@ -161,13 +149,10 @@ func (h *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn,
|
||||
} else {
|
||||
h.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
|
||||
}
|
||||
h.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
|
||||
return h.router.RoutePacketConnection(ctx, conn, metadata)
|
||||
}
|
||||
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
func (h *Inbound) Start() error {
|
||||
if h.tlsConfig != nil {
|
||||
err := h.tlsConfig.Start()
|
||||
if err != nil {
|
||||
@@ -183,7 +168,7 @@ func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
|
||||
func (h *Inbound) Close() error {
|
||||
return common.Close(
|
||||
h.listener,
|
||||
&h.listener,
|
||||
h.tlsConfig,
|
||||
common.PtrOrNil(h.service),
|
||||
)
|
||||
|
||||
@@ -69,8 +69,8 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
}
|
||||
if len(options.Down) > 0 {
|
||||
receiveBps, err = humanize.ParseBytes(options.Down)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "invalid down speed format: ", options.Down)
|
||||
if receiveBps == 0 {
|
||||
return nil, E.New("invalid down speed format: ", options.Down)
|
||||
}
|
||||
} else {
|
||||
receiveBps = uint64(options.DownMbps) * hysteria.MbpsToBps
|
||||
@@ -95,7 +95,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
return &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeHysteria, tag, networkList, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeHysteria, networkList, tag, options.DialerOptions),
|
||||
logger: logger,
|
||||
client: client,
|
||||
}, nil
|
||||
|
||||
@@ -20,7 +20,6 @@ import (
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/auth"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
@@ -109,7 +108,7 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
TLSConfig: tlsConfig,
|
||||
IgnoreClientBandwidth: options.IgnoreClientBandwidth,
|
||||
UDPTimeout: udpTimeout,
|
||||
Handler: inbound,
|
||||
Handler: adapter.NewUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, nil),
|
||||
MasqueradeHandler: masqueradeHandler,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -129,18 +128,12 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
|
||||
func (h *Inbound) newConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
|
||||
ctx = log.ContextWithNewID(ctx)
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = h.Tag()
|
||||
metadata.InboundType = h.Type()
|
||||
//nolint:staticcheck
|
||||
metadata.InboundDetour = h.listener.ListenOptions().Detour
|
||||
//nolint:staticcheck
|
||||
metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
|
||||
metadata.OriginDestination = h.listener.UDPAddr()
|
||||
metadata.Source = source
|
||||
metadata.Destination = destination
|
||||
h.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
|
||||
userID, _ := auth.UserFromContext[int](ctx)
|
||||
if userName := h.userNameList[userID]; userName != "" {
|
||||
@@ -149,21 +142,16 @@ func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, source M.S
|
||||
} else {
|
||||
h.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
|
||||
}
|
||||
h.router.RouteConnectionEx(ctx, conn, metadata, onClose)
|
||||
return h.router.RouteConnection(ctx, conn, metadata)
|
||||
}
|
||||
|
||||
func (h *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
|
||||
func (h *Inbound) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
|
||||
ctx = log.ContextWithNewID(ctx)
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = h.Tag()
|
||||
metadata.InboundType = h.Type()
|
||||
//nolint:staticcheck
|
||||
metadata.InboundDetour = h.listener.ListenOptions().Detour
|
||||
//nolint:staticcheck
|
||||
metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
|
||||
metadata.OriginDestination = h.listener.UDPAddr()
|
||||
metadata.Source = source
|
||||
metadata.Destination = destination
|
||||
h.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source)
|
||||
userID, _ := auth.UserFromContext[int](ctx)
|
||||
if userName := h.userNameList[userID]; userName != "" {
|
||||
@@ -172,13 +160,10 @@ func (h *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn,
|
||||
} else {
|
||||
h.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
|
||||
}
|
||||
h.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
|
||||
return h.router.RoutePacketConnection(ctx, conn, metadata)
|
||||
}
|
||||
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
func (h *Inbound) Start() error {
|
||||
if h.tlsConfig != nil {
|
||||
err := h.tlsConfig.Start()
|
||||
if err != nil {
|
||||
@@ -194,7 +179,7 @@ func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
|
||||
func (h *Inbound) Close() error {
|
||||
return common.Close(
|
||||
h.listener,
|
||||
&h.listener,
|
||||
h.tlsConfig,
|
||||
common.PtrOrNil(h.service),
|
||||
)
|
||||
|
||||
@@ -81,7 +81,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
return &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeHysteria2, tag, networkList, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeHysteria2, networkList, tag, options.DialerOptions),
|
||||
logger: logger,
|
||||
client: client,
|
||||
}, nil
|
||||
|
||||
@@ -54,10 +54,7 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
func (h *Inbound) Start() error {
|
||||
return h.listener.Start()
|
||||
}
|
||||
|
||||
@@ -69,11 +66,7 @@ func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata a
|
||||
err := h.newConnection(ctx, conn, metadata, onClose)
|
||||
N.CloseOnHandshakeFailure(conn, onClose, err)
|
||||
if err != nil {
|
||||
if E.IsClosedOrCanceled(err) {
|
||||
h.logger.DebugContext(ctx, "connection closed: ", err)
|
||||
} else {
|
||||
h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
|
||||
}
|
||||
h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,8 +85,6 @@ func (h *Inbound) newConnection(ctx context.Context, conn net.Conn, metadata ada
|
||||
}
|
||||
|
||||
func (h *Inbound) newUserConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||
metadata.Inbound = h.Tag()
|
||||
metadata.InboundType = h.Type()
|
||||
user, loaded := auth.UserFromContext[string](ctx)
|
||||
if !loaded {
|
||||
h.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
|
||||
@@ -106,8 +97,6 @@ func (h *Inbound) newUserConnection(ctx context.Context, conn net.Conn, metadata
|
||||
}
|
||||
|
||||
func (h *Inbound) streamUserPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||
metadata.Inbound = h.Tag()
|
||||
metadata.InboundType = h.Type()
|
||||
user, loaded := auth.UserFromContext[string](ctx)
|
||||
if !loaded {
|
||||
h.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
|
||||
|
||||
@@ -78,10 +78,7 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (n *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
func (n *Inbound) Start() error {
|
||||
var tlsConfig *tls.STDConfig
|
||||
if n.tlsConfig != nil {
|
||||
err := n.tlsConfig.Start()
|
||||
@@ -195,9 +192,7 @@ func (n *Inbound) newConnection(ctx context.Context, waitForClose bool, conn net
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = n.Tag()
|
||||
metadata.InboundType = n.Type()
|
||||
//nolint:staticcheck
|
||||
metadata.InboundDetour = n.listener.ListenOptions().Detour
|
||||
//nolint:staticcheck
|
||||
metadata.InboundOptions = n.listener.ListenOptions().InboundOptions
|
||||
metadata.Source = source
|
||||
metadata.Destination = destination
|
||||
|
||||
@@ -42,10 +42,7 @@ func NewRedirect(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return redirect, nil
|
||||
}
|
||||
|
||||
func (h *Redirect) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
func (h *Redirect) Start() error {
|
||||
return h.listener.Start()
|
||||
}
|
||||
|
||||
|
||||
@@ -61,10 +61,7 @@ func NewTProxy(ctx context.Context, router adapter.Router, logger log.ContextLog
|
||||
return tproxy, nil
|
||||
}
|
||||
|
||||
func (t *TProxy) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
func (t *TProxy) Start() error {
|
||||
err := t.listener.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -93,10 +93,7 @@ func newInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, err
|
||||
}
|
||||
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
func (h *Inbound) Start() error {
|
||||
return h.listener.Start()
|
||||
}
|
||||
|
||||
@@ -104,20 +101,14 @@ func (h *Inbound) Close() error {
|
||||
return h.listener.Close()
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||
err := h.service.NewConnection(ctx, conn, adapter.UpstreamMetadata(metadata))
|
||||
N.CloseOnHandshakeFailure(conn, onClose, err)
|
||||
if err != nil {
|
||||
if E.IsClosedOrCanceled(err) {
|
||||
h.logger.DebugContext(ctx, "connection closed: ", err)
|
||||
} else {
|
||||
h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
|
||||
}
|
||||
h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
func (h *Inbound) NewPacketEx(buffer *buf.Buffer, source M.Socksaddr) {
|
||||
err := h.service.NewPacket(h.ctx, &stubPacketConn{h.listener.PacketWriter()}, buffer, M.Metadata{Source: source})
|
||||
if err != nil {
|
||||
@@ -138,6 +129,8 @@ func (h *Inbound) newPacketConnection(ctx context.Context, conn N.PacketConn, me
|
||||
h.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
|
||||
metadata.Inbound = h.Tag()
|
||||
metadata.InboundType = h.Type()
|
||||
metadata.InboundDetour = h.listener.ListenOptions().Detour
|
||||
metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
|
||||
return h.router.RoutePacketConnection(ctx, conn, metadata)
|
||||
}
|
||||
|
||||
|
||||
@@ -101,10 +101,7 @@ func newMultiInbound(ctx context.Context, router adapter.Router, logger log.Cont
|
||||
return inbound, err
|
||||
}
|
||||
|
||||
func (h *MultiInbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
func (h *MultiInbound) Start() error {
|
||||
return h.listener.Start()
|
||||
}
|
||||
|
||||
@@ -112,20 +109,14 @@ func (h *MultiInbound) Close() error {
|
||||
return h.listener.Close()
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
func (h *MultiInbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||
err := h.service.NewConnection(ctx, conn, adapter.UpstreamMetadata(metadata))
|
||||
N.CloseOnHandshakeFailure(conn, onClose, err)
|
||||
if err != nil {
|
||||
if E.IsClosedOrCanceled(err) {
|
||||
h.logger.DebugContext(ctx, "connection closed: ", err)
|
||||
} else {
|
||||
h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
|
||||
}
|
||||
h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
func (h *MultiInbound) NewPacketEx(buffer *buf.Buffer, source M.Socksaddr) {
|
||||
err := h.service.NewPacket(h.ctx, &stubPacketConn{h.listener.PacketWriter()}, buffer, M.Metadata{Source: source})
|
||||
if err != nil {
|
||||
@@ -147,10 +138,6 @@ func (h *MultiInbound) newConnection(ctx context.Context, conn net.Conn, metadat
|
||||
h.logger.InfoContext(ctx, "[", user, "] inbound connection to ", metadata.Destination)
|
||||
metadata.Inbound = h.Tag()
|
||||
metadata.InboundType = h.Type()
|
||||
//nolint:staticcheck
|
||||
metadata.InboundDetour = h.listener.ListenOptions().Detour
|
||||
//nolint:staticcheck
|
||||
metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
|
||||
return h.router.RouteConnection(ctx, conn, metadata)
|
||||
}
|
||||
|
||||
@@ -170,14 +157,11 @@ func (h *MultiInbound) newPacketConnection(ctx context.Context, conn N.PacketCon
|
||||
h.logger.InfoContext(ctx, "[", user, "] inbound packet connection to ", metadata.Destination)
|
||||
metadata.Inbound = h.Tag()
|
||||
metadata.InboundType = h.Type()
|
||||
//nolint:staticcheck
|
||||
metadata.InboundDetour = h.listener.ListenOptions().Detour
|
||||
//nolint:staticcheck
|
||||
metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
|
||||
return h.router.RoutePacketConnection(ctx, conn, metadata)
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
func (h *MultiInbound) NewError(ctx context.Context, err error) {
|
||||
NewError(h.logger, ctx, err)
|
||||
}
|
||||
|
||||
@@ -86,10 +86,7 @@ func newRelayInbound(ctx context.Context, router adapter.Router, logger log.Cont
|
||||
return inbound, err
|
||||
}
|
||||
|
||||
func (h *RelayInbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
func (h *RelayInbound) Start() error {
|
||||
return h.listener.Start()
|
||||
}
|
||||
|
||||
@@ -97,20 +94,14 @@ func (h *RelayInbound) Close() error {
|
||||
return h.listener.Close()
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
func (h *RelayInbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||
err := h.service.NewConnection(ctx, conn, adapter.UpstreamMetadata(metadata))
|
||||
N.CloseOnHandshakeFailure(conn, onClose, err)
|
||||
if err != nil {
|
||||
if E.IsClosedOrCanceled(err) {
|
||||
h.logger.DebugContext(ctx, "connection closed: ", err)
|
||||
} else {
|
||||
h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
|
||||
}
|
||||
h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
func (h *RelayInbound) NewPacketEx(buffer *buf.Buffer, source M.Socksaddr) {
|
||||
err := h.service.NewPacket(h.ctx, &stubPacketConn{h.listener.PacketWriter()}, buffer, M.Metadata{Source: source})
|
||||
if err != nil {
|
||||
@@ -132,10 +123,6 @@ func (h *RelayInbound) newConnection(ctx context.Context, conn net.Conn, metadat
|
||||
h.logger.InfoContext(ctx, "[", destination, "] inbound connection to ", metadata.Destination)
|
||||
metadata.Inbound = h.Tag()
|
||||
metadata.InboundType = h.Type()
|
||||
//nolint:staticcheck
|
||||
metadata.InboundDetour = h.listener.ListenOptions().Detour
|
||||
//nolint:staticcheck
|
||||
metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
|
||||
return h.router.RouteConnection(ctx, conn, metadata)
|
||||
}
|
||||
|
||||
@@ -155,14 +142,11 @@ func (h *RelayInbound) newPacketConnection(ctx context.Context, conn N.PacketCon
|
||||
h.logger.InfoContext(ctx, "[", destination, "] inbound packet connection to ", metadata.Destination)
|
||||
metadata.Inbound = h.Tag()
|
||||
metadata.InboundType = h.Type()
|
||||
//nolint:staticcheck
|
||||
metadata.InboundDetour = h.listener.ListenOptions().Detour
|
||||
//nolint:staticcheck
|
||||
metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
|
||||
return h.router.RoutePacketConnection(ctx, conn, metadata)
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
func (h *RelayInbound) NewError(ctx context.Context, err error) {
|
||||
NewError(h.logger, ctx, err)
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
outbound := &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeShadowsocks, tag, options.Network.Build(), options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeShadowsocks, options.Network.Build(), tag, options.DialerOptions),
|
||||
logger: logger,
|
||||
dialer: outboundDialer,
|
||||
method: method,
|
||||
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
"github.com/sagernet/sing/common/auth"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
@@ -73,7 +72,7 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
},
|
||||
HandshakeForServerName: handshakeForServerName,
|
||||
StrictMode: options.StrictMode,
|
||||
Handler: (*inboundHandler)(inbound),
|
||||
Handler: adapter.NewUpstreamContextHandler(inbound.newConnection, nil, nil),
|
||||
Logger: logger,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -90,10 +89,7 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
func (h *Inbound) Start() error {
|
||||
return h.listener.Start()
|
||||
}
|
||||
|
||||
@@ -101,35 +97,24 @@ func (h *Inbound) Close() error {
|
||||
return h.listener.Close()
|
||||
}
|
||||
|
||||
func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||
err := h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, metadata.Source, metadata.Destination, onClose)
|
||||
N.CloseOnHandshakeFailure(conn, onClose, err)
|
||||
if err != nil {
|
||||
if E.IsClosedOrCanceled(err) {
|
||||
h.logger.DebugContext(ctx, "connection closed: ", err)
|
||||
} else {
|
||||
h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
func (h *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
|
||||
return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata))
|
||||
}
|
||||
|
||||
type inboundHandler Inbound
|
||||
|
||||
func (h *inboundHandler) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = h.Tag()
|
||||
metadata.InboundType = h.Type()
|
||||
//nolint:staticcheck
|
||||
metadata.InboundDetour = h.listener.ListenOptions().Detour
|
||||
//nolint:staticcheck
|
||||
metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
|
||||
metadata.Source = source
|
||||
metadata.Destination = destination
|
||||
func (h *Inbound) newConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
|
||||
if userName, _ := auth.UserFromContext[string](ctx); userName != "" {
|
||||
metadata.User = userName
|
||||
h.logger.InfoContext(ctx, "[", userName, "] inbound connection to ", metadata.Destination)
|
||||
} else {
|
||||
h.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
|
||||
}
|
||||
h.router.RouteConnectionEx(ctx, conn, metadata, onClose)
|
||||
return h.router.RouteConnection(ctx, conn, metadata)
|
||||
}
|
||||
|
||||
func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||
err := h.NewConnection(ctx, conn, metadata)
|
||||
N.CloseOnHandshakeFailure(conn, onClose, err)
|
||||
if err != nil {
|
||||
h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ type Outbound struct {
|
||||
|
||||
func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowTLSOutboundOptions) (adapter.Outbound, error) {
|
||||
outbound := &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeShadowTLS, tag, []string{N.NetworkTCP}, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeShadowTLS, []string{N.NetworkTCP}, tag, options.DialerOptions),
|
||||
}
|
||||
if options.TLS == nil || !options.TLS.Enabled {
|
||||
return nil, C.ErrTLSRequired
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user