mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-11-08 03:02:36 +00:00
Compare commits
308
Commits
v1.0.1
..
v1.0-beta2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6ef276811 | ||
|
|
1701aaf78c | ||
|
|
122daa4bfb | ||
|
|
561a9e5275 | ||
|
|
de2453fce9 | ||
|
|
d59d40c118 | ||
|
|
3469df001f | ||
|
|
0d8cfa3031 | ||
|
|
0289586880 | ||
|
|
e46427c7fc | ||
|
|
3ea59d9a8e | ||
|
|
e85dfc6adf | ||
|
|
d0703b78fa | ||
|
|
432e6adf3e | ||
|
|
a057754035 | ||
|
|
0348ace253 | ||
|
|
c5e38203eb | ||
|
|
9ac31d0233 | ||
|
|
9d8d1cd69d | ||
|
|
07a0381f8b | ||
|
|
f841459004 | ||
|
|
78a26fc139 | ||
|
|
9f6628445e | ||
|
|
fa017b5977 | ||
|
|
58f4a970f2 | ||
|
|
021aa8faed | ||
|
|
83f6e037d6 | ||
|
|
baf153434d | ||
|
|
d481bd7993 | ||
|
|
e859c0a6ef | ||
|
|
59a39e66b1 | ||
|
|
fd5ac69a35 | ||
|
|
a940703ae1 | ||
|
|
350729cde8 | ||
|
|
2e14cd6d66 | ||
|
|
f703524f04 | ||
|
|
aa4435c775 | ||
|
|
31a2e368cc | ||
|
|
97e284e65e | ||
|
|
a6baab92f3 | ||
|
|
7c76e0c3ee | ||
|
|
591a4fcf8e | ||
|
|
71dac85600 | ||
|
|
ad90ddd327 | ||
|
|
03f457f3d0 | ||
|
|
a878256367 | ||
|
|
553f78ed55 | ||
|
|
1bc7d2237e | ||
|
|
132222013b | ||
|
|
2008fb552a | ||
|
|
236c034c62 | ||
|
|
f87baf08d3 | ||
|
|
22aa0c2f40 | ||
|
|
88469d4aaa | ||
|
|
1413c5022a | ||
|
|
aa8cdaee22 | ||
|
|
9f6ff54a76 | ||
|
|
e750c747c6 | ||
|
|
9edfe7d9d3 | ||
|
|
c9b7acd22c | ||
|
|
2ba2f0298c | ||
|
|
a24a2b475a | ||
|
|
4005452772 | ||
|
|
d4b7e221f0 | ||
|
|
77c98fd042 | ||
|
|
082872b2f3 | ||
|
|
6253e2e24c | ||
|
|
4216afe62f | ||
|
|
8fec78a5cd | ||
|
|
7ba0a14e97 | ||
|
|
3a442347a5 | ||
|
|
c4f4fd97d6 | ||
|
|
ac0ead1473 | ||
|
|
83cea9475d | ||
|
|
dc6bb7ab1b | ||
|
|
c71f6ba377 | ||
|
|
b1b1ab5350 | ||
|
|
7613b8dbfe | ||
|
|
e4cece6095 | ||
|
|
bcefe8716f | ||
|
|
746b5d8be0 | ||
|
|
f13ecbd9bb | ||
|
|
e839beb73b | ||
|
|
b797cdf91e | ||
|
|
84e4677a94 | ||
|
|
0377a11719 | ||
|
|
d0fa79044a | ||
|
|
f381f8d35a | ||
|
|
92e1e5b893 | ||
|
|
8e8b4dba22 | ||
|
|
767cd55817 | ||
|
|
eb0ef439d6 | ||
|
|
0bf78c0a8a | ||
|
|
12d7e19f32 | ||
|
|
d1c3dd0ee1 | ||
|
|
3dfa99efe1 | ||
|
|
d7bd221a47 | ||
|
|
1b7a3b4a74 | ||
|
|
c8424ed8fd | ||
|
|
150df1ae8e | ||
|
|
5ca9d77176 | ||
|
|
aa89fcc29d | ||
|
|
7ead0de26b | ||
|
|
f22c2690ec | ||
|
|
738bb0eabc | ||
|
|
002a519a17 | ||
|
|
f51128f772 | ||
|
|
d6a0aa7ccf | ||
|
|
ca94a2ddcb | ||
|
|
835ae1217b | ||
|
|
c165969399 | ||
|
|
88c69a06dc | ||
|
|
cd5e7055d2 | ||
|
|
3157593b6b | ||
|
|
c8399a297e | ||
|
|
529cfe2d9a | ||
|
|
50869c6cd2 | ||
|
|
44fcfab9aa | ||
|
|
340fce9f1c | ||
|
|
51bbf93ff2 | ||
|
|
f8d13d79c7 | ||
|
|
b0ed1dc106 | ||
|
|
ef8dde2b70 | ||
|
|
97870c9288 | ||
|
|
c9226aeaaf | ||
|
|
7b30815938 | ||
|
|
517a89fa9c | ||
|
|
cf80073f27 | ||
|
|
43353ca5a4 | ||
|
|
b79b19c470 | ||
|
|
ccdfab378a | ||
|
|
0e6b4df8f1 | ||
|
|
79a4b18ec7 | ||
|
|
e05ee55545 | ||
|
|
ecaddd897e | ||
|
|
8ca6c246a8 | ||
|
|
55d9a0ef2f | ||
|
|
4067e0f25c | ||
|
|
6d78cf6b58 | ||
|
|
df6635c620 | ||
|
|
2c6d239525 | ||
|
|
0f74f6cd60 | ||
|
|
6ee10c03d1 | ||
|
|
587739e95c | ||
|
|
01bace7769 | ||
|
|
dfa10d4ebe | ||
|
|
f691bd5ce1 | ||
|
|
64dbac8138 | ||
|
|
1c3c154d6d | ||
|
|
32201cacda | ||
|
|
5f566b140f | ||
|
|
03890151d7 | ||
|
|
8e4de29409 | ||
|
|
f6f3390490 | ||
|
|
d4cce1b5b9 | ||
|
|
44068500bf | ||
|
|
8ce263669e | ||
|
|
6b4824ffba | ||
|
|
9a8918cb9e | ||
|
|
b1c2440371 | ||
|
|
37b11e614c | ||
|
|
14b6200fd8 | ||
|
|
7966b80476 | ||
|
|
b526ab2746 | ||
|
|
0e0a892b7e | ||
|
|
fe3649cd27 | ||
|
|
e014220508 | ||
|
|
d06fd03dd8 | ||
|
|
0eed0ca11a | ||
|
|
c57ea9e47c | ||
|
|
70b4577dbe | ||
|
|
5f1f55fbe7 | ||
|
|
2d3d46eb34 | ||
|
|
2ce09b6ffd | ||
|
|
d3378a575c | ||
|
|
9b9b5ebb72 | ||
|
|
0f7f800e95 | ||
|
|
457de86819 | ||
|
|
83154eadd3 | ||
|
|
c0a2f77258 | ||
|
|
c240f1b359 | ||
|
|
aa074a2063 | ||
|
|
f008d0bde3 | ||
|
|
0347a7c038 | ||
|
|
75508bccb5 | ||
|
|
593799a988 | ||
|
|
816d7b734c | ||
|
|
5491895a60 | ||
|
|
9394674b63 | ||
|
|
146008a631 | ||
|
|
cc78f0347d | ||
|
|
1f05420745 | ||
|
|
32e2730ec6 | ||
|
|
29c329dc52 | ||
|
|
7d8a7c5c7d | ||
|
|
9e9e6f7ee6 | ||
|
|
fde33fbb30 | ||
|
|
67edc163cb | ||
|
|
fe8e984608 | ||
|
|
7d340e7ef9 | ||
|
|
af19ba6119 | ||
|
|
8666631732 | ||
|
|
ce4b7231e2 | ||
|
|
21641be9d1 | ||
|
|
5f6f33c464 | ||
|
|
4abf669d09 | ||
|
|
187de6c738 | ||
|
|
884c0cf595 | ||
|
|
9f8978bbcf | ||
|
|
bcdf71deb3 | ||
|
|
7bc7b72c61 | ||
|
|
e531e89b4b | ||
|
|
e5e24ef51d | ||
|
|
c4e46c35b5 | ||
|
|
139127f1e4 | ||
|
|
3838d3070d | ||
|
|
8004ff51f0 | ||
|
|
385c42e638 | ||
|
|
6327c4b40c | ||
|
|
45643fbed1 | ||
|
|
6ac1b395cf | ||
|
|
c5b3e8b042 | ||
|
|
c7fabe40ed | ||
|
|
3fb011712b | ||
|
|
6b1a68908d | ||
|
|
d1e83882e5 | ||
|
|
cf845d946e | ||
|
|
4094c94971 | ||
|
|
ae36e35de7 | ||
|
|
a4b5c61e25 | ||
|
|
9caa37c12a | ||
|
|
9871ed955b | ||
|
|
afc2f509a4 | ||
|
|
fe5618c35d | ||
|
|
8619e07d66 | ||
|
|
eb35d6793e | ||
|
|
a25db09aac | ||
|
|
8969a15858 | ||
|
|
377f3f83a2 | ||
|
|
5a3de62c50 | ||
|
|
2c2eb31e18 | ||
|
|
e13b72afca | ||
|
|
b9086b31e6 | ||
|
|
de2db7c2d2 | ||
|
|
238afda9da | ||
|
|
e7d557fd9e | ||
|
|
4fc763cfa2 | ||
|
|
b47f3adbb3 | ||
|
|
862e3c430c | ||
|
|
dc127e2994 | ||
|
|
3c1190e2c3 | ||
|
|
a104d18277 | ||
|
|
6048b1e270 | ||
|
|
0ef2e330e3 | ||
|
|
b417bd5be4 | ||
|
|
7f84191748 | ||
|
|
29f78248dc | ||
|
|
638f8a52d1 | ||
|
|
4432cc2253 | ||
|
|
730144cc26 | ||
|
|
c463d0cf80 | ||
|
|
8eecae92b2 | ||
|
|
6832451561 | ||
|
|
41925b6606 | ||
|
|
211d97ff8a | ||
|
|
8fa953a516 | ||
|
|
7f8c9ffa30 | ||
|
|
f448b6b977 | ||
|
|
e0cfc33fe2 | ||
|
|
76236a0b75 | ||
|
|
0cb9d79044 | ||
|
|
eeaee94e5e | ||
|
|
ddbdac7d97 | ||
|
|
b44a1cd823 | ||
|
|
d6d02b9924 | ||
|
|
3699a57847 | ||
|
|
d45007b501 | ||
|
|
9c256afc1a | ||
|
|
538a1f5909 | ||
|
|
ecac383477 | ||
|
|
8a761d7e3b | ||
|
|
651c4b539a | ||
|
|
81330d32e0 | ||
|
|
3696e81eb4 | ||
|
|
46f28a9de9 | ||
|
|
dcd7ca78fc | ||
|
|
86a38a1c7e | ||
|
|
2d9203ee74 | ||
|
|
8392567962 | ||
|
|
f76102dab5 | ||
|
|
43cf0441db | ||
|
|
792dc83778 | ||
|
|
718b4afbf3 | ||
|
|
13f41f59d6 | ||
|
|
ca5b782106 | ||
|
|
8e7f215514 | ||
|
|
4fc4eb09b0 | ||
|
|
18e3f43df3 | ||
|
|
28b865acf0 | ||
|
|
dd56b2584b | ||
|
|
70c0812606 | ||
|
|
ef5cfd59d4 | ||
|
|
85a695caa1 | ||
|
|
30444057bd | ||
|
|
6eae8e361f | ||
|
|
7c57eb70e8 | ||
|
|
9f4c0ff624 | ||
|
|
60691819b1 |
@@ -31,7 +31,7 @@ body:
|
||||
<details>
|
||||
|
||||
```console
|
||||
$ sing-box version
|
||||
$ sing-box --version
|
||||
# Paste output here
|
||||
```
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
PROJECTS=$(dirname "$0")/../..
|
||||
go get -x github.com/sagernet/$1@$(git -C $PROJECTS/$1 rev-parse HEAD)
|
||||
|
||||
go get -x github.com/sagernet/sing@$(git -C $PROJECTS/sing rev-parse HEAD)
|
||||
go get -x github.com/sagernet/sing-dns@$(git -C $PROJECTS/sing-dns rev-parse HEAD)
|
||||
go get -x github.com/sagernet/sing-tun@$(git -C $PROJECTS/sing-tun rev-parse HEAD)
|
||||
go get -x github.com/sagernet/sing-shadowsocks@$(git -C $PROJECTS/sing-shadowsocks rev-parse HEAD)
|
||||
go get -x github.com/sagernet/sing-vmess@$(git -C $PROJECTS/sing-vmess rev-parse HEAD)
|
||||
go mod tidy
|
||||
|
||||
@@ -4,7 +4,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- dev-next
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- '.github/**'
|
||||
@@ -12,7 +11,6 @@ on:
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
- dev-next
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
@@ -2,7 +2,7 @@ name: Generate Documents
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- main
|
||||
paths:
|
||||
- docs/**
|
||||
- .github/workflows/mkdocs.yml
|
||||
|
||||
+2
-2
@@ -7,8 +7,8 @@ ENV GOPROXY ${GOPROXY}
|
||||
ENV CGO_ENABLED=0
|
||||
RUN set -ex \
|
||||
&& apk add git build-base \
|
||||
&& export COMMIT=$(git rev-parse --short HEAD) \
|
||||
&& go build -v -trimpath -tags 'no_gvisor,with_quic,with_wireguard,with_acme' \
|
||||
&& export COMMIT=$(git rev-parse HEAD) \
|
||||
&& go build -v -trimpath -tags 'with_quic,with_acme,with_wireguard,with_clash_api' \
|
||||
-o /go/bin/sing-box \
|
||||
-ldflags "-X github.com/sagernet/sing-box/constant.Commit=${COMMIT} -w -s -buildid=" \
|
||||
./cmd/sing-box
|
||||
|
||||
@@ -2,13 +2,11 @@ package adapter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/sagernet/sing-box/common/process"
|
||||
"github.com/sagernet/sing-dns"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
type Inbound interface {
|
||||
@@ -17,13 +15,6 @@ type Inbound interface {
|
||||
Tag() string
|
||||
}
|
||||
|
||||
type InjectableInbound interface {
|
||||
Inbound
|
||||
Network() []string
|
||||
NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
|
||||
NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
|
||||
}
|
||||
|
||||
type InboundContext struct {
|
||||
Inbound string
|
||||
InboundType string
|
||||
@@ -38,8 +29,6 @@ type InboundContext struct {
|
||||
|
||||
// cache
|
||||
|
||||
InboundDetour string
|
||||
LastInbound string
|
||||
OriginDestination M.Socksaddr
|
||||
DomainStrategy dns.DomainStrategy
|
||||
SniffEnabled bool
|
||||
|
||||
@@ -138,7 +138,7 @@ func New(ctx context.Context, options option.Options) (*Box, error) {
|
||||
}
|
||||
outbounds = append(outbounds, out)
|
||||
}
|
||||
err = router.Initialize(inbounds, outbounds, func() adapter.Outbound {
|
||||
err = router.Initialize(outbounds, func() adapter.Outbound {
|
||||
out, oErr := outbound.New(ctx, router, logFactory.NewLogger("outbound/direct"), option.Outbound{Type: "direct", Tag: "default"})
|
||||
common.Must(oErr)
|
||||
outbounds = append(outbounds, out)
|
||||
|
||||
@@ -38,7 +38,7 @@ func format() error {
|
||||
return E.Cause(err, "read config")
|
||||
}
|
||||
var options option.Options
|
||||
err = options.UnmarshalJSON(configContent)
|
||||
err = json.Unmarshal(configContent, &options)
|
||||
if err != nil {
|
||||
return E.Cause(err, "decode config")
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/sagernet/sing-box"
|
||||
"github.com/sagernet/sing-box/common/json"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
@@ -45,7 +46,7 @@ func readConfig() (option.Options, error) {
|
||||
return option.Options{}, E.Cause(err, "read config")
|
||||
}
|
||||
var options option.Options
|
||||
err = options.UnmarshalJSON(configContent)
|
||||
err = json.Unmarshal(configContent, &options)
|
||||
if err != nil {
|
||||
return option.Options{}, E.Cause(err, "decode config")
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
package baderror
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
func Contains(err error, msgList ...string) bool {
|
||||
for _, msg := range msgList {
|
||||
if strings.Contains(err.Error(), msg) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func WrapH2(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
err = E.Unwrap(err)
|
||||
if err == io.ErrUnexpectedEOF {
|
||||
return io.EOF
|
||||
}
|
||||
if Contains(err, "client disconnected", "body closed by handler") {
|
||||
return net.ErrClosed
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func WrapGRPC(err error) error {
|
||||
// grpc uses stupid internal error types
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if Contains(err, "EOF") {
|
||||
return io.EOF
|
||||
}
|
||||
if Contains(err, "Canceled") {
|
||||
return context.Canceled
|
||||
}
|
||||
if Contains(err,
|
||||
"the client connection is closing",
|
||||
"server closed the stream without sending trailers") {
|
||||
return net.ErrClosed
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func WrapQUIC(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if Contains(err, "canceled with error code 0") {
|
||||
return net.ErrClosed
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing/common/control"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
@@ -131,9 +130,6 @@ func NewDefault(router adapter.Router, options option.DialerOptions) *DefaultDia
|
||||
}
|
||||
|
||||
func (d *DefaultDialer) DialContext(ctx context.Context, network string, address M.Socksaddr) (net.Conn, error) {
|
||||
if !address.IsValid() {
|
||||
return nil, E.New("invalid address")
|
||||
}
|
||||
switch N.NetworkName(network) {
|
||||
case N.NetworkUDP:
|
||||
return d.udpDialer.DialContext(ctx, network, address.String())
|
||||
|
||||
@@ -10,12 +10,15 @@ import (
|
||||
)
|
||||
|
||||
func New(router adapter.Router, options option.DialerOptions) N.Dialer {
|
||||
var dialer N.Dialer
|
||||
if options.Detour == "" {
|
||||
dialer = NewDefault(router, options)
|
||||
return NewDefault(router, options)
|
||||
} else {
|
||||
dialer = NewDetour(router, options.Detour)
|
||||
return NewDetour(router, options.Detour)
|
||||
}
|
||||
}
|
||||
|
||||
func NewOutbound(router adapter.Router, options option.OutboundDialerOptions) N.Dialer {
|
||||
dialer := New(router, options.DialerOptions)
|
||||
domainStrategy := dns.DomainStrategy(options.DomainStrategy)
|
||||
if domainStrategy != dns.DomainStrategyAsIS || options.Detour == "" {
|
||||
dialer = NewResolveDialer(router, dialer, domainStrategy, time.Duration(options.FallbackDelay))
|
||||
|
||||
@@ -51,7 +51,7 @@ func (d *ResolveDialer) DialContext(ctx context.Context, network string, destina
|
||||
}
|
||||
|
||||
func (d *ResolveDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||
if !destination.IsFqdn() {
|
||||
if !destination.IsFqdn() || destination.Fqdn == "" {
|
||||
return d.dialer.ListenPacket(ctx, destination)
|
||||
}
|
||||
ctx, metadata := adapter.AppendContext(ctx)
|
||||
|
||||
@@ -22,13 +22,13 @@ func (s *androidSearcher) FindProcessInfo(ctx context.Context, network string, s
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if sharedPackage, loaded := s.packageManager.SharedPackageByID(uid % 100000); loaded {
|
||||
if sharedPackage, loaded := s.packageManager.SharedPackageByID(uid); loaded {
|
||||
return &Info{
|
||||
UserId: int32(uid),
|
||||
PackageName: sharedPackage,
|
||||
}, nil
|
||||
}
|
||||
if packageName, loaded := s.packageManager.PackageByID(uid % 100000); loaded {
|
||||
if packageName, loaded := s.packageManager.PackageByID(uid); loaded {
|
||||
return &Info{
|
||||
UserId: int32(uid),
|
||||
PackageName: packageName,
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
package redir
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
)
|
||||
|
||||
const (
|
||||
PF_OUT = 0x2
|
||||
DIOCNATLOOK = 0xc0544417
|
||||
)
|
||||
|
||||
func GetOriginalDestination(conn net.Conn) (destination netip.AddrPort, err error) {
|
||||
fd, err := syscall.Open("/dev/pf", 0, syscall.O_RDONLY)
|
||||
if err != nil {
|
||||
return netip.AddrPort{}, err
|
||||
}
|
||||
defer syscall.Close(fd)
|
||||
nl := struct {
|
||||
saddr, daddr, rsaddr, rdaddr [16]byte
|
||||
sxport, dxport, rsxport, rdxport [4]byte
|
||||
af, proto, protoVariant, direction uint8
|
||||
}{
|
||||
af: syscall.AF_INET,
|
||||
proto: syscall.IPPROTO_TCP,
|
||||
direction: PF_OUT,
|
||||
}
|
||||
la := conn.LocalAddr().(*net.TCPAddr)
|
||||
ra := conn.RemoteAddr().(*net.TCPAddr)
|
||||
raIP, laIP := ra.IP, la.IP
|
||||
raPort, laPort := ra.Port, la.Port
|
||||
switch {
|
||||
case raIP.To4() != nil:
|
||||
copy(nl.saddr[:net.IPv4len], raIP.To4())
|
||||
copy(nl.daddr[:net.IPv4len], laIP.To4())
|
||||
nl.af = syscall.AF_INET
|
||||
default:
|
||||
copy(nl.saddr[:], raIP.To16())
|
||||
copy(nl.daddr[:], laIP.To16())
|
||||
nl.af = syscall.AF_INET6
|
||||
}
|
||||
nl.sxport[0], nl.sxport[1] = byte(raPort>>8), byte(raPort)
|
||||
nl.dxport[0], nl.dxport[1] = byte(laPort>>8), byte(laPort)
|
||||
if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), DIOCNATLOOK, uintptr(unsafe.Pointer(&nl))); errno != 0 {
|
||||
return netip.AddrPort{}, errno
|
||||
}
|
||||
|
||||
var ip net.IP
|
||||
switch nl.af {
|
||||
case syscall.AF_INET:
|
||||
ip = make(net.IP, net.IPv4len)
|
||||
copy(ip, nl.rdaddr[:net.IPv4len])
|
||||
case syscall.AF_INET6:
|
||||
ip = make(net.IP, net.IPv6len)
|
||||
copy(ip, nl.rdaddr[:])
|
||||
}
|
||||
port := uint16(nl.rdxport[0])<<8 | uint16(nl.rdxport[1])
|
||||
destination = netip.AddrPortFrom(M.AddrFromIP(ip), port)
|
||||
return
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
//go:build !linux && !darwin
|
||||
//go:build !linux
|
||||
|
||||
package redir
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ const (
|
||||
TypeHysteria = "hysteria"
|
||||
TypeTor = "tor"
|
||||
TypeSSH = "ssh"
|
||||
TypeShadowTLS = "shadowtls"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package constant
|
||||
|
||||
var (
|
||||
Version = "1.0.1"
|
||||
Version = "1.0-beta2"
|
||||
Commit = ""
|
||||
)
|
||||
|
||||
+1
-39
@@ -1,41 +1,3 @@
|
||||
#### 1.0.1
|
||||
|
||||
* Fix match 4in6 address in ip_cidr
|
||||
* Fix clash api log level format error
|
||||
* Fix clash api unknown proxy type
|
||||
|
||||
#### 1.0
|
||||
|
||||
* Fix wireguard reconnect
|
||||
* Fix naive inbound
|
||||
* Fix json format error message
|
||||
* Fix processing vmess termination signal
|
||||
* Fix hysteria stream error
|
||||
* Fix listener close when proxyproto failed
|
||||
|
||||
#### 1.0-rc1
|
||||
|
||||
* Fix write log timestamp
|
||||
* Fix write zero
|
||||
* Fix dial parallel in direct outbound
|
||||
* Fix write trojan udp
|
||||
* Fix DNS routing
|
||||
* Add attribute support for geosite
|
||||
* Update documentation for [Dial Fields](/configuration/shared/dial)
|
||||
|
||||
#### 1.0-beta3
|
||||
|
||||
* Add [chained inbound](/configuration/shared/listen#detour) support
|
||||
* Add process_path rule item
|
||||
* Add macOS redirect support
|
||||
* Add ShadowTLS [Inbound](/configuration/inbound/shadowtls), [Outbound](/configuration/outbound/shadowtls)
|
||||
and [Examples](/examples/shadowtls)
|
||||
* Fix search android package in non-owner users
|
||||
* Fix socksaddr type condition
|
||||
* Fix smux session status
|
||||
* Refactor inbound and outbound documentation
|
||||
* Minor fixes
|
||||
|
||||
#### 1.0-beta2
|
||||
|
||||
* Add strict_route option for [Tun inbound](/configuration/inbound/tun#strict_route)
|
||||
@@ -149,4 +111,4 @@
|
||||
|
||||
No changelog before.
|
||||
|
||||
[#9]: https://github.com/SagerNet/sing-box/pull/9
|
||||
[#9]: https://github.com/SagerNet/sing-box/pull/9
|
||||
@@ -61,9 +61,6 @@
|
||||
"process_name": [
|
||||
"curl"
|
||||
],
|
||||
"process_path": [
|
||||
"/usr/bin/curl"
|
||||
],
|
||||
"package_name": [
|
||||
"com.termux"
|
||||
],
|
||||
@@ -180,14 +177,6 @@ Match port range.
|
||||
|
||||
Match process name.
|
||||
|
||||
#### process_path
|
||||
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux, Windows, and macOS.
|
||||
|
||||
Match process path.
|
||||
|
||||
#### package_name
|
||||
|
||||
Match android package name.
|
||||
|
||||
@@ -60,9 +60,6 @@
|
||||
"process_name": [
|
||||
"curl"
|
||||
],
|
||||
"process_path": [
|
||||
"/usr/bin/curl"
|
||||
],
|
||||
"package_name": [
|
||||
"com.termux"
|
||||
],
|
||||
@@ -179,14 +176,6 @@
|
||||
|
||||
匹配进程名称。
|
||||
|
||||
#### process_path
|
||||
|
||||
!!! error ""
|
||||
|
||||
仅支持 Linux、Windows 和 macOS.
|
||||
|
||||
匹配进程路径。
|
||||
|
||||
#### package_name
|
||||
|
||||
匹配 Android 应用包名。
|
||||
|
||||
@@ -4,22 +4,29 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct-in",
|
||||
|
||||
... // Listen Fields
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 5353,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"udp_timeout": 300,
|
||||
"proxy_protocol": false,
|
||||
|
||||
"network": "udp",
|
||||
"override_address": "1.0.0.1",
|
||||
"override_port": 53
|
||||
"network": "udp",
|
||||
"override_address": "1.0.0.1",
|
||||
"override_port": 53
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Listen Fields
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen) for details.
|
||||
|
||||
### Fields
|
||||
### Direct Fields
|
||||
|
||||
#### network
|
||||
|
||||
@@ -33,4 +40,50 @@ Override the connection destination address.
|
||||
|
||||
#### override_port
|
||||
|
||||
Override the connection destination port.
|
||||
Override the connection destination port.
|
||||
|
||||
### Listen Fields
|
||||
|
||||
#### listen
|
||||
|
||||
==Required==
|
||||
|
||||
Listen address.
|
||||
|
||||
#### listen_port
|
||||
|
||||
==Required==
|
||||
|
||||
Listen port.
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
Enable tcp fast open for listener.
|
||||
|
||||
#### sniff
|
||||
|
||||
Enable sniffing.
|
||||
|
||||
See [Protocol Sniff](/configuration/route/sniff/) for details.
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
Override the connection destination address with the sniffed domain.
|
||||
|
||||
If the domain name is invalid (like tor), this will not work.
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the requested domain name will be resolved to IP before routing.
|
||||
|
||||
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
|
||||
|
||||
#### udp_timeout
|
||||
|
||||
UDP NAT expiration time in seconds, default is 300 (5 minutes).
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
Parse [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header.
|
||||
@@ -4,22 +4,29 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct-in",
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct-in",
|
||||
|
||||
... // 监听字段
|
||||
|
||||
"network": "udp",
|
||||
"override_address": "1.0.0.1",
|
||||
"override_port": 53
|
||||
"listen": "::",
|
||||
"listen_port": 5353,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"udp_timeout": 300,
|
||||
|
||||
"network": "udp",
|
||||
"proxy_protocol": false,
|
||||
"override_address": "1.0.0.1",
|
||||
"override_port": 53
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 监听字段
|
||||
|
||||
参阅 [监听字段](/zh/configuration/shared/listen/)。
|
||||
|
||||
### 字段
|
||||
### Direct 字段
|
||||
|
||||
#### network
|
||||
|
||||
@@ -35,3 +42,48 @@
|
||||
|
||||
覆盖连接目标端口。
|
||||
|
||||
### 监听字段
|
||||
|
||||
#### listen
|
||||
|
||||
==必填==
|
||||
|
||||
监听地址。
|
||||
|
||||
#### listen_port
|
||||
|
||||
==必填==
|
||||
|
||||
监听端口。
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
为监听器启用 TCP 快速打开。
|
||||
|
||||
#### sniff
|
||||
|
||||
启用协议探测。
|
||||
|
||||
参阅 [协议探测](/zh/configuration/route/sniff/)
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
用探测出的域名覆盖连接目标地址。
|
||||
|
||||
如果域名无效(如 Tor),将不生效。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,请求的域名将在路由之前解析为 IP。
|
||||
|
||||
如果 `sniff_override_destination` 生效,它的值将作为后备。
|
||||
|
||||
#### udp_timeout
|
||||
|
||||
UDP NAT 过期时间,以秒为单位,默认为 300(5 分钟)。
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
|
||||
|
||||
@@ -2,27 +2,33 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"tag": "http-in",
|
||||
|
||||
... // Listen Fields
|
||||
|
||||
"users": [
|
||||
"inbounds": [
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "admin"
|
||||
"type": "http",
|
||||
"tag": "http-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 2080,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"proxy_protocol": false,
|
||||
|
||||
"users": [
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "admin"
|
||||
}
|
||||
],
|
||||
"tls": {},
|
||||
"set_system_proxy": false
|
||||
}
|
||||
],
|
||||
"tls": {},
|
||||
"set_system_proxy": false
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Listen Fields
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen) for details.
|
||||
|
||||
### Fields
|
||||
### HTTP Fields
|
||||
|
||||
#### tls
|
||||
|
||||
@@ -41,3 +47,45 @@ No authentication required if empty.
|
||||
Only supported on Linux, Android, Windows, and macOS.
|
||||
|
||||
Automatically set system proxy configuration when start and clean up when stop.
|
||||
|
||||
### Listen Fields
|
||||
|
||||
#### listen
|
||||
|
||||
==Required==
|
||||
|
||||
Listen address.
|
||||
|
||||
#### listen_port
|
||||
|
||||
==Required==
|
||||
|
||||
Listen port.
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
Enable tcp fast open for listener.
|
||||
|
||||
#### sniff
|
||||
|
||||
Enable sniffing.
|
||||
|
||||
See [Protocol Sniff](/configuration/route/sniff/) for details.
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
Override the connection destination address with the sniffed domain.
|
||||
|
||||
If the domain name is invalid (like tor), this will not work.
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the requested domain name will be resolved to IP before routing.
|
||||
|
||||
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
Parse [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header.
|
||||
@@ -2,27 +2,33 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"tag": "http-in",
|
||||
|
||||
... // 监听字段
|
||||
|
||||
"users": [
|
||||
"inbounds": [
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "admin"
|
||||
"type": "http",
|
||||
"tag": "http-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 2080,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"proxy_protocol": false,
|
||||
|
||||
"users": [
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "admin"
|
||||
}
|
||||
],
|
||||
"tls": {},
|
||||
"set_system_proxy": false
|
||||
}
|
||||
],
|
||||
"tls": {},
|
||||
"set_system_proxy": false
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 监听字段
|
||||
|
||||
参阅 [监听字段](/zh/configuration/shared/listen/)。
|
||||
|
||||
### 字段
|
||||
### HTTP 字段
|
||||
|
||||
#### tls
|
||||
|
||||
@@ -32,7 +38,7 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
|
||||
|
||||
HTTP 用户
|
||||
|
||||
如果为空则不需要验证。
|
||||
默认不需要验证。
|
||||
|
||||
#### set_system_proxy
|
||||
|
||||
@@ -40,4 +46,46 @@ HTTP 用户
|
||||
|
||||
仅支持 Linux、Android、Windows 和 macOS。
|
||||
|
||||
启动时自动设置系统代理,停止时自动清理。
|
||||
启动时自动设置系统代理,停止时自动清理。
|
||||
|
||||
### 监听字段
|
||||
|
||||
#### listen
|
||||
|
||||
==必填==
|
||||
|
||||
监听地址。
|
||||
|
||||
#### listen_port
|
||||
|
||||
==必填==
|
||||
|
||||
监听端口。
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
为监听器启用 TCP 快速打开。
|
||||
|
||||
#### sniff
|
||||
|
||||
启用协议探测。
|
||||
|
||||
参阅 [协议探测](/zh/configuration/route/sniff/)
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
用探测出的域名覆盖连接目标地址。
|
||||
|
||||
如果域名无效(如 Tor),将不生效。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,请求的域名将在路由之前解析为 IP。
|
||||
|
||||
如果 `sniff_override_destination` 生效,它的值将作为后备。
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
|
||||
|
||||
@@ -2,23 +2,31 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "hysteria",
|
||||
"tag": "hysteria-in",
|
||||
|
||||
... // Listen Fields
|
||||
|
||||
"up": "100 Mbps",
|
||||
"up_mbps": 100,
|
||||
"down": "100 Mbps",
|
||||
"down_mbps": 100,
|
||||
"obfs": "fuck me till the daylight",
|
||||
"auth": "",
|
||||
"auth_str": "password",
|
||||
"recv_window_conn": 0,
|
||||
"recv_window_client": 0,
|
||||
"max_conn_client": 0,
|
||||
"disable_mtu_discovery": false,
|
||||
"tls": {}
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "hysteria",
|
||||
"tag": "hysteria-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 443,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
|
||||
"up": "100 Mbps",
|
||||
"up_mbps": 100,
|
||||
"down": "100 Mbps",
|
||||
"down_mbps": 100,
|
||||
"obfs": "fuck me till the daylight",
|
||||
"auth": "",
|
||||
"auth_str": "password",
|
||||
"recv_window_conn": 0,
|
||||
"recv_window_client": 0,
|
||||
"max_conn_client": 0,
|
||||
"disable_mtu_discovery": false,
|
||||
"tls": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -26,11 +34,7 @@
|
||||
|
||||
QUIC, which is required by hysteria is not included by default, see [Installation](/#installation).
|
||||
|
||||
### Listen Fields
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen) for details.
|
||||
|
||||
### Fields
|
||||
### Hysteria Fields
|
||||
|
||||
#### up, down
|
||||
|
||||
@@ -97,4 +101,38 @@ Force enabled on for systems other than Linux and Windows (according to upstream
|
||||
|
||||
==Required==
|
||||
|
||||
TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
|
||||
TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
|
||||
|
||||
### Listen Fields
|
||||
|
||||
#### listen
|
||||
|
||||
==Required==
|
||||
|
||||
Listen address.
|
||||
|
||||
#### listen_port
|
||||
|
||||
==Required==
|
||||
|
||||
Listen port.
|
||||
|
||||
#### sniff
|
||||
|
||||
Enable sniffing.
|
||||
|
||||
See [Protocol Sniff](/configuration/route/sniff/) for details.
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
Override the connection destination address with the sniffed domain.
|
||||
|
||||
If the domain name is invalid (like tor), this will not work.
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the requested domain name will be resolved to IP before routing.
|
||||
|
||||
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
|
||||
|
||||
@@ -2,23 +2,31 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "hysteria",
|
||||
"tag": "hysteria-in",
|
||||
|
||||
... // 监听字段
|
||||
|
||||
"up": "100 Mbps",
|
||||
"up_mbps": 100,
|
||||
"down": "100 Mbps",
|
||||
"down_mbps": 100,
|
||||
"obfs": "fuck me till the daylight",
|
||||
"auth": "",
|
||||
"auth_str": "password",
|
||||
"recv_window_conn": 0,
|
||||
"recv_window_client": 0,
|
||||
"max_conn_client": 0,
|
||||
"disable_mtu_discovery": false,
|
||||
"tls": {}
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "hysteria",
|
||||
"tag": "hysteria-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 443,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
|
||||
"up": "100 Mbps",
|
||||
"up_mbps": 100,
|
||||
"down": "100 Mbps",
|
||||
"down_mbps": 100,
|
||||
"obfs": "fuck me till the daylight",
|
||||
"auth": "",
|
||||
"auth_str": "password",
|
||||
"recv_window_conn": 0,
|
||||
"recv_window_client": 0,
|
||||
"max_conn_client": 0,
|
||||
"disable_mtu_discovery": false,
|
||||
"tls": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -26,11 +34,7 @@
|
||||
|
||||
默认安装不包含被 Hysteria 依赖的 QUIC,参阅 [安装](/zh/#_2)。
|
||||
|
||||
### 监听字段
|
||||
|
||||
参阅 [监听字段](/zh/configuration/shared/listen/)。
|
||||
|
||||
### 字段
|
||||
### Hysteria 字段
|
||||
|
||||
#### up, down
|
||||
|
||||
@@ -97,4 +101,38 @@ base64 编码的认证密码。
|
||||
|
||||
==必填==
|
||||
|
||||
TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
|
||||
TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
|
||||
|
||||
### 监听字段
|
||||
|
||||
#### listen
|
||||
|
||||
==必填==
|
||||
|
||||
监听地址。
|
||||
|
||||
#### listen_port
|
||||
|
||||
==必填==
|
||||
|
||||
监听端口。
|
||||
|
||||
#### sniff
|
||||
|
||||
启用协议探测。
|
||||
|
||||
参阅 [协议探测](/zh/configuration/route/sniff/)。
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
用探测出的域名覆盖连接目标地址。
|
||||
|
||||
如果域名无效(如 Tor),将不生效。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,请求的域名将在路由之前解析为 IP。
|
||||
|
||||
如果 `sniff_override_destination` 生效,它的值将作为后备。
|
||||
@@ -15,20 +15,20 @@
|
||||
|
||||
### Fields
|
||||
|
||||
| Type | Format | Injectable |
|
||||
|---------------|------------------------------|------------|
|
||||
| `direct` | [Direct](./direct) | X |
|
||||
| `mixed` | [Mixed](./mixed) | TCP |
|
||||
| `socks` | [SOCKS](./socks) | TCP |
|
||||
| `http` | [HTTP](./http) | TCP |
|
||||
| `shadowsocks` | [Shadowsocks](./shadowsocks) | TCP |
|
||||
| `vmess` | [VMess](./vmess) | TCP |
|
||||
| `trojan` | [Trojan](./trojan) | TCP |
|
||||
| `naive` | [Naive](./naive) | X |
|
||||
| `hysteria` | [Hysteria](./hysteria) | X |
|
||||
| `tun` | [Tun](./tun) | X |
|
||||
| `redirect` | [Redirect](./redirect) | X |
|
||||
| `tproxy` | [TProxy](./tproxy) | X |
|
||||
| Type | Format |
|
||||
|---------------|------------------------------|
|
||||
| `direct` | [Direct](./direct) |
|
||||
| `mixed` | [Mixed](./mixed) |
|
||||
| `socks` | [SOCKS](./socks) |
|
||||
| `http` | [HTTP](./http) |
|
||||
| `shadowsocks` | [Shadowsocks](./shadowsocks) |
|
||||
| `vmess` | [VMess](./vmess) |
|
||||
| `trojan` | [Trojan](./trojan) |
|
||||
| `naive` | [Naive](./naive) |
|
||||
| `hysteria` | [Hysteria](./hysteria) |
|
||||
| `tun` | [Tun](./tun) |
|
||||
| `redirect` | [Redirect](./redirect) |
|
||||
| `tproxy` | [TProxy](./tproxy) |
|
||||
|
||||
#### tag
|
||||
|
||||
|
||||
@@ -15,20 +15,20 @@
|
||||
|
||||
### 字段
|
||||
|
||||
| 类型 | 格式 | 注入支持 |
|
||||
|---------------|------------------------------|------|
|
||||
| `direct` | [Direct](./direct) | X |
|
||||
| `mixed` | [Mixed](./mixed) | TCP |
|
||||
| `socks` | [SOCKS](./socks) | TCP |
|
||||
| `http` | [HTTP](./http) | TCP |
|
||||
| `shadowsocks` | [Shadowsocks](./shadowsocks) | TCP |
|
||||
| `vmess` | [VMess](./vmess) | TCP |
|
||||
| `trojan` | [Trojan](./trojan) | TCP |
|
||||
| `naive` | [Naive](./naive) | X |
|
||||
| `hysteria` | [Hysteria](./hysteria) | X |
|
||||
| `tun` | [Tun](./tun) | X |
|
||||
| `redirect` | [Redirect](./redirect) | X |
|
||||
| `tproxy` | [TProxy](./tproxy) | X |
|
||||
| 类型 | 格式 |
|
||||
|---------------|------------------------------|
|
||||
| `direct` | [Direct](./direct) |
|
||||
| `mixed` | [Mixed](./mixed) |
|
||||
| `socks` | [SOCKS](./socks) |
|
||||
| `http` | [HTTP](./http) |
|
||||
| `shadowsocks` | [Shadowsocks](./shadowsocks) |
|
||||
| `vmess` | [VMess](./vmess) |
|
||||
| `trojan` | [Trojan](./trojan) |
|
||||
| `naive` | [Naive](./naive) |
|
||||
| `hysteria` | [Hysteria](./hysteria) |
|
||||
| `tun` | [Tun](./tun) |
|
||||
| `redirect` | [Redirect](./redirect) |
|
||||
| `tproxy` | [TProxy](./tproxy) |
|
||||
|
||||
#### tag
|
||||
|
||||
|
||||
@@ -4,26 +4,32 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "mixed",
|
||||
"tag": "mixed-in",
|
||||
|
||||
... // Listen Fields
|
||||
|
||||
"users": [
|
||||
"inbounds": [
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "admin"
|
||||
"type": "mixed",
|
||||
"tag": "mixed-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 2080,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"proxy_protocol": false,
|
||||
|
||||
"users": [
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "admin"
|
||||
}
|
||||
],
|
||||
"set_system_proxy": false
|
||||
}
|
||||
],
|
||||
"set_system_proxy": false
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Listen Fields
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen) for details.
|
||||
|
||||
### Fields
|
||||
### Mixed Fields
|
||||
|
||||
#### users
|
||||
|
||||
@@ -33,6 +39,52 @@ No authentication required if empty.
|
||||
|
||||
#### set_system_proxy
|
||||
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux, Android, Windows, and macOS.
|
||||
|
||||
Automatically set system proxy configuration when start and clean up when stop.
|
||||
|
||||
### Listen Fields
|
||||
|
||||
#### listen
|
||||
|
||||
==Required==
|
||||
|
||||
Listen address.
|
||||
|
||||
#### listen_port
|
||||
|
||||
==Required==
|
||||
|
||||
Listen port.
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
Enable tcp fast open for listener.
|
||||
|
||||
#### sniff
|
||||
|
||||
Enable sniffing.
|
||||
|
||||
See [Protocol Sniff](/configuration/route/sniff/) for details.
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
Override the connection destination address with the sniffed domain.
|
||||
|
||||
If the domain name is invalid (like tor), this will not work.
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the requested domain name will be resolved to IP before routing.
|
||||
|
||||
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
|
||||
|
||||
#### set_system_proxy
|
||||
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux, Android, Windows, and macOS.
|
||||
|
||||
@@ -4,32 +4,38 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "mixed",
|
||||
"tag": "mixed-in",
|
||||
|
||||
... // 监听字段
|
||||
|
||||
"users": [
|
||||
"inbounds": [
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "admin"
|
||||
"type": "mixed",
|
||||
"tag": "mixed-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 2080,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"proxy_protocol": false,
|
||||
|
||||
"users": [
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "admin"
|
||||
}
|
||||
],
|
||||
"set_system_proxy": false
|
||||
}
|
||||
],
|
||||
"set_system_proxy": false
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 监听字段
|
||||
|
||||
参阅 [监听字段](/zh/configuration/shared/listen/)。
|
||||
|
||||
### 字段
|
||||
### Mixed 字段
|
||||
|
||||
#### users
|
||||
|
||||
SOCKS 和 HTTP 用户
|
||||
|
||||
如果为空则不需要验证。
|
||||
默认不需要验证。
|
||||
|
||||
#### set_system_proxy
|
||||
|
||||
@@ -37,4 +43,46 @@ SOCKS 和 HTTP 用户
|
||||
|
||||
仅支持 Linux、Android、Windows 和 macOS。
|
||||
|
||||
启动时自动设置系统代理,停止时自动清理。
|
||||
启动时自动设置系统代理,停止时自动清理。
|
||||
|
||||
### 监听字段
|
||||
|
||||
#### listen
|
||||
|
||||
==必填==
|
||||
|
||||
监听地址。
|
||||
|
||||
#### listen_port
|
||||
|
||||
==必填==
|
||||
|
||||
监听端口。
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
为监听器启用 TCP 快速打开。
|
||||
|
||||
#### sniff
|
||||
|
||||
启用协议探测。
|
||||
|
||||
参阅 [协议探测](/zh/configuration/route/sniff/)。
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
用探测出的域名覆盖连接目标地址。
|
||||
|
||||
如果域名无效(如 Tor),将不生效。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,请求的域名将在路由之前解析为 IP。
|
||||
|
||||
如果 `sniff_override_destination` 生效,它的值将作为后备。
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
|
||||
|
||||
@@ -2,19 +2,29 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "naive",
|
||||
"tag": "naive-in",
|
||||
"network": "udp",
|
||||
|
||||
... // Listen Fields
|
||||
|
||||
"users": [
|
||||
"inbounds": [
|
||||
{
|
||||
"username": "sekai",
|
||||
"password": "password"
|
||||
"type": "naive",
|
||||
"tag": "naive-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 443,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"proxy_protocol": false,
|
||||
|
||||
"network": "udp",
|
||||
"users": [
|
||||
{
|
||||
"username": "sekai",
|
||||
"password": "password"
|
||||
}
|
||||
],
|
||||
"tls": {}
|
||||
}
|
||||
],
|
||||
"tls": {}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -22,11 +32,7 @@
|
||||
|
||||
HTTP3 transport is not included by default, see [Installation](/#installation).
|
||||
|
||||
### Listen Fields
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen) for details.
|
||||
|
||||
### Fields
|
||||
### Naive Fields
|
||||
|
||||
#### network
|
||||
|
||||
@@ -42,4 +48,46 @@ Naive users.
|
||||
|
||||
#### tls
|
||||
|
||||
TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
|
||||
TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
|
||||
|
||||
### Listen Fields
|
||||
|
||||
#### listen
|
||||
|
||||
==Required==
|
||||
|
||||
Listen address.
|
||||
|
||||
#### listen_port
|
||||
|
||||
==Required==
|
||||
|
||||
Listen port.
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
Enable tcp fast open for listener.
|
||||
|
||||
#### sniff
|
||||
|
||||
Enable sniffing.
|
||||
|
||||
See [Protocol Sniff](/configuration/route/sniff/) for details.
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
Override the connection destination address with the sniffed domain.
|
||||
|
||||
If the domain name is invalid (like tor), this will not work.
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the requested domain name will be resolved to IP before routing.
|
||||
|
||||
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
Parse [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header.
|
||||
@@ -2,19 +2,29 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "naive",
|
||||
"tag": "naive-in",
|
||||
"network": "udp",
|
||||
|
||||
... // 监听字段
|
||||
|
||||
"users": [
|
||||
"inbounds": [
|
||||
{
|
||||
"username": "sekai",
|
||||
"password": "password"
|
||||
"type": "naive",
|
||||
"tag": "naive-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 443,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"proxy_protocol": false,
|
||||
|
||||
"network": "udp",
|
||||
"users": [
|
||||
{
|
||||
"username": "sekai",
|
||||
"password": "password"
|
||||
}
|
||||
],
|
||||
"tls": {}
|
||||
}
|
||||
],
|
||||
"tls": {}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -22,11 +32,7 @@
|
||||
|
||||
默认安装不包含 HTTP3 传输层, 参阅 [安装](/zh/#_2)。
|
||||
|
||||
### 监听字段
|
||||
|
||||
参阅 [监听字段](/zh/configuration/shared/listen/)。
|
||||
|
||||
### 字段
|
||||
### Naive 字段
|
||||
|
||||
#### network
|
||||
|
||||
@@ -42,4 +48,46 @@ Naive 用户。
|
||||
|
||||
#### tls
|
||||
|
||||
TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
|
||||
TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
|
||||
|
||||
### 监听字段
|
||||
|
||||
#### listen
|
||||
|
||||
==必填==
|
||||
|
||||
监听地址。
|
||||
|
||||
#### listen_port
|
||||
|
||||
==必填==
|
||||
|
||||
监听端口。
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
为监听器启用 TCP 快速打开。
|
||||
|
||||
#### sniff
|
||||
|
||||
启用协议探测。
|
||||
|
||||
参阅 [协议探测](/zh/configuration/route/sniff/)。
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
用探测出的域名覆盖连接目标地址。
|
||||
|
||||
如果域名无效(如 Tor),将不生效。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,请求的域名将在路由之前解析为 IP。
|
||||
|
||||
如果 `sniff_override_destination` 生效,它的值将作为后备。
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
|
||||
|
||||
@@ -1,18 +1,52 @@
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux and macOS.
|
||||
|
||||
### Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "redirect",
|
||||
"tag": "redirect-in",
|
||||
|
||||
... // Listen Fields
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "redirect",
|
||||
"tag": "redirect-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 5353,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Listen Fields
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen) for details.
|
||||
#### listen
|
||||
|
||||
==Required==
|
||||
|
||||
Listen address.
|
||||
|
||||
#### listen_port
|
||||
|
||||
==Required==
|
||||
|
||||
Listen port.
|
||||
|
||||
#### sniff
|
||||
|
||||
Enable sniffing.
|
||||
|
||||
See [Protocol Sniff](/configuration/route/sniff/) for details.
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
Override the connection destination address with the sniffed domain.
|
||||
|
||||
If the domain name is invalid (like tor), this will not work.
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the requested domain name will be resolved to IP before routing.
|
||||
|
||||
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
|
||||
@@ -1,17 +1,52 @@
|
||||
!!! error ""
|
||||
|
||||
仅支持 Linux 和 macOS。
|
||||
|
||||
### 结构
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "redirect",
|
||||
"tag": "redirect-in",
|
||||
|
||||
... // 监听字段
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "redirect",
|
||||
"tag": "redirect-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 5353,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 监听字段
|
||||
|
||||
参阅 [监听字段](/zh/configuration/shared/listen/)。
|
||||
#### listen
|
||||
|
||||
==必填==
|
||||
|
||||
监听地址。
|
||||
|
||||
#### listen_port
|
||||
|
||||
==必填==
|
||||
|
||||
监听端口。
|
||||
|
||||
#### sniff
|
||||
|
||||
启用协议探测。
|
||||
|
||||
参阅 [协议探测](/zh/configuration/route/sniff/)。
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
用探测出的域名覆盖连接目标地址。
|
||||
|
||||
如果域名无效(如 Tor),将不生效。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,请求的域名将在路由之前解析为 IP。
|
||||
|
||||
如果 `sniff_override_destination` 生效,它的值将作为后备。
|
||||
@@ -2,13 +2,25 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "shadowsocks",
|
||||
"tag": "ss-in",
|
||||
|
||||
... // Listen Fields
|
||||
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg=="
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "shadowsocks",
|
||||
"tag": "ss-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 5353,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"udp_timeout": 300,
|
||||
"network": "udp",
|
||||
"proxy_protocol": false,
|
||||
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg=="
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -16,12 +28,17 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"users": [
|
||||
"inbounds": [
|
||||
{
|
||||
"name": "sekai",
|
||||
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
|
||||
"type": "shadowsocks",
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"users": [
|
||||
{
|
||||
"name": "sekai",
|
||||
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -31,25 +48,25 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "shadowsocks",
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"destinations": [
|
||||
"inbounds": [
|
||||
{
|
||||
"name": "test",
|
||||
"server": "example.com",
|
||||
"server_port": 8080,
|
||||
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
|
||||
"type": "shadowsocks",
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"destinations": [
|
||||
{
|
||||
"name": "test",
|
||||
"server": "example.com",
|
||||
"server_port": 8080,
|
||||
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Listen Fields
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen) for details.
|
||||
|
||||
### Fields
|
||||
### Shadowsocks Fields
|
||||
|
||||
#### network
|
||||
|
||||
|
||||
@@ -2,13 +2,25 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "shadowsocks",
|
||||
"tag": "ss-in",
|
||||
|
||||
... // 监听字段
|
||||
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg=="
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "shadowsocks",
|
||||
"tag": "ss-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 5353,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"udp_timeout": 300,
|
||||
"network": "udp",
|
||||
"proxy_protocol": false,
|
||||
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg=="
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -16,12 +28,17 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"users": [
|
||||
"inbounds": [
|
||||
{
|
||||
"name": "sekai",
|
||||
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
|
||||
"type": "shadowsocks",
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"users": [
|
||||
{
|
||||
"name": "sekai",
|
||||
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -31,25 +48,25 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "shadowsocks",
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"destinations": [
|
||||
"inbounds": [
|
||||
{
|
||||
"name": "test",
|
||||
"server": "example.com",
|
||||
"server_port": 8080,
|
||||
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
|
||||
"type": "shadowsocks",
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"destinations": [
|
||||
{
|
||||
"name": "test",
|
||||
"server": "example.com",
|
||||
"server_port": 8080,
|
||||
"password": "PCD2Z4o12bKUoFa3cC97Hw=="
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Listen Fields
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen) for details.
|
||||
|
||||
### 字段
|
||||
### Shadowsocks 字段
|
||||
|
||||
#### network
|
||||
|
||||
@@ -81,4 +98,50 @@ See [Listen Fields](/configuration/shared/listen) for details.
|
||||
|---------------|-------------------------------|
|
||||
| none | / |
|
||||
| 2022 methods | `openssl rand -base64 <密钥长度>` |
|
||||
| other methods | 任意字符串 |
|
||||
| other methods | 任意字符串 |
|
||||
|
||||
### 监听字段
|
||||
|
||||
#### listen
|
||||
|
||||
==必填==
|
||||
|
||||
监听地址。
|
||||
|
||||
#### listen_port
|
||||
|
||||
==必填==
|
||||
|
||||
监听端口。
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
为监听器启用 TCP 快速打开。
|
||||
|
||||
#### sniff
|
||||
|
||||
启用协议探测。
|
||||
|
||||
参阅 [协议探测](/zh/configuration/route/sniff/)。
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
用探测出的域名覆盖连接目标地址。
|
||||
|
||||
如果域名无效(如 Tor),将不生效。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,请求的域名将在路由之前解析为 IP。
|
||||
|
||||
如果 `sniff_override_destination` 生效,它的值将作为后备。
|
||||
|
||||
#### udp_timeout
|
||||
|
||||
UDP NAT 过期时间,以秒为单位,默认为 300(5 分钟)。
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
### Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "shadowtls",
|
||||
"tag": "st-in",
|
||||
|
||||
... // Listen Fields
|
||||
|
||||
"handshake": {
|
||||
"server": "google.com",
|
||||
"server_port": 443,
|
||||
|
||||
... // Dial Fields
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Listen Fields
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen) for details.
|
||||
|
||||
|
||||
### Fields
|
||||
|
||||
#### handshake
|
||||
|
||||
==Required==
|
||||
|
||||
Handshake server address and [dial options](/configuration/shared/dial).
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
### 结构
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "shadowtls",
|
||||
"tag": "st-in",
|
||||
|
||||
... // 监听字段
|
||||
|
||||
"handshake": {
|
||||
"server": "google.com",
|
||||
"server_port": 443,
|
||||
|
||||
... // 拨号字段
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 监听字段
|
||||
|
||||
参阅 [监听字段](/zh/configuration/shared/listen/)。
|
||||
|
||||
### 字段
|
||||
|
||||
#### handshake
|
||||
|
||||
==必填==
|
||||
|
||||
握手服务器地址和 [拨号参数](/zh/configuration/shared/dial/)。
|
||||
@@ -4,28 +4,76 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "socks-in",
|
||||
|
||||
... // Listen Fields
|
||||
|
||||
"users": [
|
||||
"inbounds": [
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "admin"
|
||||
"type": "socks",
|
||||
"tag": "socks-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 2080,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"proxy_protocol": false,
|
||||
|
||||
"users": [
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "admin"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Listen Fields
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen) for details.
|
||||
|
||||
### Fields
|
||||
### SOCKS Fields
|
||||
|
||||
#### users
|
||||
|
||||
SOCKS users.
|
||||
|
||||
No authentication required if empty.
|
||||
|
||||
### Listen Fields
|
||||
|
||||
#### listen
|
||||
|
||||
==Required==
|
||||
|
||||
Listen address.
|
||||
|
||||
#### listen_port
|
||||
|
||||
==Required==
|
||||
|
||||
Listen port.
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
Enable tcp fast open for listener.
|
||||
|
||||
#### sniff
|
||||
|
||||
Enable sniffing.
|
||||
|
||||
See [Protocol Sniff](/configuration/route/sniff/) for details.
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
Override the connection destination address with the sniffed domain.
|
||||
|
||||
If the domain name is invalid (like tor), this will not work.
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the requested domain name will be resolved to IP before routing.
|
||||
|
||||
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
Parse [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header.
|
||||
|
||||
@@ -4,28 +4,76 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "socks-in",
|
||||
|
||||
... // 监听字段
|
||||
|
||||
"users": [
|
||||
"inbounds": [
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "admin"
|
||||
"type": "socks",
|
||||
"tag": "socks-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 2080,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"proxy_protocol": false,
|
||||
|
||||
"users": [
|
||||
{
|
||||
"username": "admin",
|
||||
"password": "admin"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 监听字段
|
||||
|
||||
参阅 [监听字段](/zh/configuration/shared/listen/)。
|
||||
|
||||
### 字段
|
||||
### SOCKS 字段
|
||||
|
||||
#### users
|
||||
|
||||
SOCKS 用户
|
||||
|
||||
如果为空则不需要验证。
|
||||
默认不需要验证。
|
||||
|
||||
### Listen Fields
|
||||
|
||||
#### listen
|
||||
|
||||
==必填==
|
||||
|
||||
监听地址。
|
||||
|
||||
#### listen_port
|
||||
|
||||
==必填==
|
||||
|
||||
监听端口。
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
为监听器启用 TCP 快速打开。
|
||||
|
||||
#### sniff
|
||||
|
||||
启用协议探测。
|
||||
|
||||
参阅 [协议探测](/zh/configuration/route/sniff/)。
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
用探测出的域名覆盖连接目标地址。
|
||||
|
||||
如果域名无效(如 Tor),将不生效。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,请求的域名将在路由之前解析为 IP。
|
||||
|
||||
如果 `sniff_override_destination` 生效,它的值将作为后备。
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
|
||||
@@ -1,28 +1,67 @@
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux.
|
||||
|
||||
### Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "tproxy",
|
||||
"tag": "tproxy-in",
|
||||
|
||||
... // Listen Fields
|
||||
|
||||
"network": "udp"
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "tproxy",
|
||||
"tag": "tproxy-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 5353,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"udp_timeout": 300,
|
||||
|
||||
"network": "udp"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Listen Fields
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen) for details.
|
||||
|
||||
### Fields
|
||||
### TProxy Fields
|
||||
|
||||
#### network
|
||||
|
||||
Listen network, one of `tcp` `udp`.
|
||||
|
||||
Both if empty.
|
||||
|
||||
### Listen Fields
|
||||
|
||||
#### listen
|
||||
|
||||
==Required==
|
||||
|
||||
Listen address.
|
||||
|
||||
#### listen_port
|
||||
|
||||
==Required==
|
||||
|
||||
Listen port.
|
||||
|
||||
#### sniff
|
||||
|
||||
Enable sniffing.
|
||||
|
||||
See [Protocol Sniff](/configuration/route/sniff/) for details.
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
Override the connection destination address with the sniffed domain.
|
||||
|
||||
If the domain name is invalid (like tor), this will not work.
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the requested domain name will be resolved to IP before routing.
|
||||
|
||||
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
|
||||
|
||||
#### udp_timeout
|
||||
|
||||
UDP NAT expiration time in seconds, default is 300 (5 minutes).
|
||||
|
||||
@@ -1,28 +1,67 @@
|
||||
!!! error ""
|
||||
|
||||
仅支持 Linux。
|
||||
|
||||
### 结构
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "tproxy",
|
||||
"tag": "tproxy-in",
|
||||
|
||||
... // 监听字段
|
||||
|
||||
"network": "udp"
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "tproxy",
|
||||
"tag": "tproxy-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 5353,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"udp_timeout": 300,
|
||||
|
||||
"network": "udp"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 监听字段
|
||||
|
||||
参阅 [监听字段](/zh/configuration/shared/listen/)。
|
||||
|
||||
### 字段
|
||||
### TProxy 字段
|
||||
|
||||
#### network
|
||||
|
||||
监听的网络协议,`tcp` `udp` 之一。
|
||||
|
||||
默认所有。
|
||||
|
||||
### 监听字段
|
||||
|
||||
#### listen
|
||||
|
||||
==必填==
|
||||
|
||||
监听地址。
|
||||
|
||||
#### listen_port
|
||||
|
||||
==必填==
|
||||
|
||||
监听端口。
|
||||
|
||||
#### sniff
|
||||
|
||||
启用协议探测。
|
||||
|
||||
参阅 [协议探测](/zh/configuration/route/sniff/)。
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
用探测出的域名覆盖连接目标地址。
|
||||
|
||||
如果域名无效(如 Tor),将不生效。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,请求的域名将在路由之前解析为 IP。
|
||||
|
||||
如果 `sniff_override_destination` 生效,它的值将作为后备。
|
||||
|
||||
#### udp_timeout
|
||||
|
||||
UDP NAT 过期时间,以秒为单位,默认为 300(5 分钟)。
|
||||
@@ -2,37 +2,43 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "trojan",
|
||||
"tag": "trojan-in",
|
||||
|
||||
... // Listen Fields
|
||||
|
||||
"users": [
|
||||
"inbounds": [
|
||||
{
|
||||
"name": "sekai",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg=="
|
||||
"type": "trojan",
|
||||
"tag": "trojan-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 2080,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"proxy_protocol": false,
|
||||
|
||||
"users": [
|
||||
{
|
||||
"name": "sekai",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg=="
|
||||
}
|
||||
],
|
||||
"tls": {},
|
||||
"fallback": {
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8080
|
||||
},
|
||||
"fallback_for_alpn": {
|
||||
"http/1.1": {
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8081
|
||||
}
|
||||
},
|
||||
"transport": {}
|
||||
}
|
||||
],
|
||||
"tls": {},
|
||||
"fallback": {
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8080
|
||||
},
|
||||
"fallback_for_alpn": {
|
||||
"http/1.1": {
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8081
|
||||
}
|
||||
},
|
||||
"transport": {}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Listen Fields
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen) for details.
|
||||
|
||||
### Fields
|
||||
### Trojan Fields
|
||||
|
||||
#### users
|
||||
|
||||
@@ -61,3 +67,45 @@ If not empty, TLS fallback requests with ALPN not in this table will be rejected
|
||||
#### transport
|
||||
|
||||
V2Ray Transport configuration, see [V2Ray Transport](/configuration/shared/v2ray-transport).
|
||||
|
||||
### Listen Fields
|
||||
|
||||
#### listen
|
||||
|
||||
==Required==
|
||||
|
||||
Listen address.
|
||||
|
||||
#### listen_port
|
||||
|
||||
==Required==
|
||||
|
||||
Listen port.
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
Enable tcp fast open for listener.
|
||||
|
||||
#### sniff
|
||||
|
||||
Enable sniffing.
|
||||
|
||||
See [Protocol Sniff](/configuration/route/sniff/) for details.
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
Override the connection destination address with the sniffed domain.
|
||||
|
||||
If the domain name is invalid (like tor), this will not work.
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the requested domain name will be resolved to IP before routing.
|
||||
|
||||
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
Parse [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header.
|
||||
@@ -2,37 +2,41 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "trojan",
|
||||
"tag": "trojan-in",
|
||||
|
||||
... // 监听字段
|
||||
|
||||
"users": [
|
||||
"inbounds": [
|
||||
{
|
||||
"name": "sekai",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg=="
|
||||
"type": "trojan",
|
||||
"tag": "trojan-in",
|
||||
"listen": "::",
|
||||
"listen_port": 2080,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"proxy_protocol": false,
|
||||
"users": [
|
||||
{
|
||||
"name": "sekai",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg=="
|
||||
}
|
||||
],
|
||||
"tls": {},
|
||||
"fallback": {
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8080
|
||||
},
|
||||
"fallback_for_alpn": {
|
||||
"http/1.1": {
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8081
|
||||
}
|
||||
},
|
||||
"transport": {}
|
||||
}
|
||||
],
|
||||
"tls": {},
|
||||
"fallback": {
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8080
|
||||
},
|
||||
"fallback_for_alpn": {
|
||||
"http/1.1": {
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8081
|
||||
}
|
||||
},
|
||||
"transport": {}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 监听字段
|
||||
|
||||
参阅 [监听字段](/zh/configuration/shared/listen/)。
|
||||
|
||||
### 字段
|
||||
### Trojan 字段
|
||||
|
||||
#### users
|
||||
|
||||
@@ -50,7 +54,7 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
|
||||
|
||||
!!! error ""
|
||||
|
||||
没有证据表明 GFW 基于 HTTP 响应检测并阻止 Trojan 服务器,并且在服务器上打开标准 http/s 端口是一个更大的特征。
|
||||
没有证据表明 GFW 基于 HTTP 响应检测并阻止木马服务器,并且在服务器上打开标准 http/s 端口是一个更大的特征。
|
||||
|
||||
回退服务器配置。如果 `fallback` 和 `fallback_for_alpn` 为空,则禁用回退。
|
||||
|
||||
@@ -62,4 +66,46 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
|
||||
|
||||
#### transport
|
||||
|
||||
V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-transport)。
|
||||
V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-transport)。
|
||||
|
||||
### 监听字段
|
||||
|
||||
#### listen
|
||||
|
||||
==必填==
|
||||
|
||||
监听地址。
|
||||
|
||||
#### listen_port
|
||||
|
||||
==必填==
|
||||
|
||||
监听端口。
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
为监听器启用 TCP 快速打开。
|
||||
|
||||
#### sniff
|
||||
|
||||
启用协议探测。
|
||||
|
||||
参阅 [协议探测](/zh/configuration/route/sniff/)。
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
用探测出的域名覆盖连接目标地址。
|
||||
|
||||
如果域名无效(如 Tor),将不生效。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,请求的域名将在路由之前解析为 IP。
|
||||
|
||||
如果 `sniff_override_destination` 生效,它的值将作为后备。
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
|
||||
|
||||
@@ -6,41 +6,48 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "tun",
|
||||
"tag": "tun-in",
|
||||
|
||||
"interface_name": "tun0",
|
||||
"inet4_address": "172.19.0.1/30",
|
||||
"inet6_address": "fdfe:dcba:9876::1/128",
|
||||
"mtu": 1500,
|
||||
"auto_route": true,
|
||||
"strict_route": true,
|
||||
"endpoint_independent_nat": false,
|
||||
"stack": "gvisor",
|
||||
"include_uid": [
|
||||
0
|
||||
],
|
||||
"include_uid_range": [
|
||||
"1000-99999"
|
||||
],
|
||||
"exclude_uid": [
|
||||
1000
|
||||
],
|
||||
"exclude_uid_range": [
|
||||
"1000-99999"
|
||||
],
|
||||
"include_android_user": [
|
||||
0,
|
||||
10
|
||||
],
|
||||
"include_package": [
|
||||
"com.android.chrome"
|
||||
],
|
||||
"exclude_package": [
|
||||
"com.android.captiveportallogin"
|
||||
],
|
||||
|
||||
... // Listen Fields
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "tun",
|
||||
"tag": "tun-in",
|
||||
"interface_name": "tun0",
|
||||
"inet4_address": "172.19.0.1/30",
|
||||
"inet6_address": "fdfe:dcba:9876::1/128",
|
||||
"mtu": 1500,
|
||||
"auto_route": true,
|
||||
"strict_route": true,
|
||||
"endpoint_independent_nat": false,
|
||||
"udp_timeout": 300,
|
||||
"stack": "gvisor",
|
||||
"include_uid": [
|
||||
0
|
||||
],
|
||||
"include_uid_range": [
|
||||
[
|
||||
"1000-99999"
|
||||
]
|
||||
],
|
||||
"exclude_uid": [
|
||||
1000
|
||||
],
|
||||
"exclude_uid_range": [
|
||||
"1000-99999"
|
||||
],
|
||||
"include_android_user": [
|
||||
0,
|
||||
10
|
||||
],
|
||||
"include_package": [
|
||||
"com.android.chrome"
|
||||
],
|
||||
"exclude_package": [
|
||||
"com.android.captiveportallogin"
|
||||
],
|
||||
"sniff": true,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv4"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -52,7 +59,7 @@
|
||||
|
||||
If tun is running in non-privileged mode, addresses and MTU will not be configured automatically, please make sure the settings are accurate.
|
||||
|
||||
### Fields
|
||||
### Tun Fields
|
||||
|
||||
#### interface_name
|
||||
|
||||
@@ -156,4 +163,22 @@ Exclude android packages in route.
|
||||
|
||||
### Listen Fields
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen) for details.
|
||||
#### sniff
|
||||
|
||||
Enable sniffing.
|
||||
|
||||
See [Protocol Sniff](/configuration/route/sniff/) for details.
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
Override the connection destination address with the sniffed domain.
|
||||
|
||||
If the domain name is invalid (like tor), this will not work.
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the requested domain name will be resolved to IP before routing.
|
||||
|
||||
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
|
||||
@@ -6,41 +6,48 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "tun",
|
||||
"tag": "tun-in",
|
||||
|
||||
"interface_name": "tun0",
|
||||
"inet4_address": "172.19.0.1/30",
|
||||
"inet6_address": "fdfe:dcba:9876::1/128",
|
||||
"mtu": 1500,
|
||||
"auto_route": true,
|
||||
"strict_route": true,
|
||||
"endpoint_independent_nat": false,
|
||||
"stack": "gvisor",
|
||||
"include_uid": [
|
||||
0
|
||||
],
|
||||
"include_uid_range": [
|
||||
"1000-99999"
|
||||
],
|
||||
"exclude_uid": [
|
||||
1000
|
||||
],
|
||||
"exclude_uid_range": [
|
||||
"1000-99999"
|
||||
],
|
||||
"include_android_user": [
|
||||
0,
|
||||
10
|
||||
],
|
||||
"include_package": [
|
||||
"com.android.chrome"
|
||||
],
|
||||
"exclude_package": [
|
||||
"com.android.captiveportallogin"
|
||||
],
|
||||
|
||||
... // 监听字段
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "tun",
|
||||
"tag": "tun-in",
|
||||
"interface_name": "tun0",
|
||||
"inet4_address": "172.19.0.1/30",
|
||||
"inet6_address": "fdfe:dcba:9876::1/128",
|
||||
"mtu": 1500,
|
||||
"auto_route": true,
|
||||
"strict_route": true,
|
||||
"endpoint_independent_nat": false,
|
||||
"udp_timeout": 300,
|
||||
"stack": "gvisor",
|
||||
"include_uid": [
|
||||
0
|
||||
],
|
||||
"include_uid_range": [
|
||||
[
|
||||
"1000-99999"
|
||||
]
|
||||
],
|
||||
"exclude_uid": [
|
||||
1000
|
||||
],
|
||||
"exclude_uid_range": [
|
||||
"1000-99999"
|
||||
],
|
||||
"include_android_user": [
|
||||
0,
|
||||
10
|
||||
],
|
||||
"include_package": [
|
||||
"com.android.chrome"
|
||||
],
|
||||
"exclude_package": [
|
||||
"com.android.captiveportallogin"
|
||||
],
|
||||
"sniff": true,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv4"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -155,4 +162,22 @@ TCP/IP 栈。
|
||||
|
||||
### 监听字段
|
||||
|
||||
参阅 [监听字段](/zh/configuration/shared/listen/)。
|
||||
#### sniff
|
||||
|
||||
启用协议探测。
|
||||
|
||||
参阅 [协议探测](/zh/configuration/route/sniff/)。
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
用探测出的域名覆盖连接目标地址。
|
||||
|
||||
如果域名无效(如 Tor),将不生效。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,请求的域名将在路由之前解析为 IP。
|
||||
|
||||
如果 `sniff_override_destination` 生效,它的值将作为后备。
|
||||
|
||||
@@ -2,28 +2,34 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "vmess",
|
||||
"tag": "vmess-in",
|
||||
|
||||
... // Listen Fields
|
||||
|
||||
"users": [
|
||||
"inbounds": [
|
||||
{
|
||||
"name": "sekai",
|
||||
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
|
||||
"alterId": 0
|
||||
"type": "vmess",
|
||||
"tag": "vmess-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 2080,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"proxy_protocol": false,
|
||||
|
||||
"users": [
|
||||
{
|
||||
"name": "sekai",
|
||||
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
|
||||
"alterId": 0
|
||||
}
|
||||
],
|
||||
"tls": {},
|
||||
"transport": {}
|
||||
}
|
||||
],
|
||||
"tls": {},
|
||||
"transport": {}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Listen Fields
|
||||
|
||||
See [Listen Fields](/configuration/shared/listen) for details.
|
||||
|
||||
### Fields
|
||||
### VMess Fields
|
||||
|
||||
#### users
|
||||
|
||||
@@ -47,3 +53,45 @@ TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
|
||||
#### transport
|
||||
|
||||
V2Ray Transport configuration, see [V2Ray Transport](/configuration/shared/v2ray-transport).
|
||||
|
||||
### Listen Fields
|
||||
|
||||
#### listen
|
||||
|
||||
==Required==
|
||||
|
||||
Listen address.
|
||||
|
||||
#### listen_port
|
||||
|
||||
==Required==
|
||||
|
||||
Listen port.
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
Enable tcp fast open for listener.
|
||||
|
||||
#### sniff
|
||||
|
||||
Enable sniffing.
|
||||
|
||||
See [Protocol Sniff](/configuration/route/sniff/) for details.
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
Override the connection destination address with the sniffed domain.
|
||||
|
||||
If the domain name is invalid (like tor), this will not work.
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the requested domain name will be resolved to IP before routing.
|
||||
|
||||
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
Parse [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header.
|
||||
@@ -2,28 +2,34 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "vmess",
|
||||
"tag": "vmess-in",
|
||||
|
||||
... // 监听字段
|
||||
|
||||
"users": [
|
||||
"inbounds": [
|
||||
{
|
||||
"name": "sekai",
|
||||
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
|
||||
"alterId": 0
|
||||
"type": "vmess",
|
||||
"tag": "vmess-in",
|
||||
|
||||
"listen": "::",
|
||||
"listen_port": 2080,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"proxy_protocol": false,
|
||||
|
||||
"users": [
|
||||
{
|
||||
"name": "sekai",
|
||||
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
|
||||
"alterId": 0
|
||||
}
|
||||
],
|
||||
"tls": {},
|
||||
"transport": {}
|
||||
}
|
||||
],
|
||||
"tls": {},
|
||||
"transport": {}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 监听字段
|
||||
|
||||
参阅 [监听字段](/zh/configuration/shared/listen/)。
|
||||
|
||||
### 字段
|
||||
### VMess 字段
|
||||
|
||||
#### users
|
||||
|
||||
@@ -47,3 +53,45 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#inbound)。
|
||||
#### transport
|
||||
|
||||
V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-transport)。
|
||||
|
||||
### 监听字段
|
||||
|
||||
#### listen
|
||||
|
||||
==必填==
|
||||
|
||||
监听地址。
|
||||
|
||||
#### listen_port
|
||||
|
||||
==必填==
|
||||
|
||||
监听端口。
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
为监听器启用 TCP 快速打开。
|
||||
|
||||
#### sniff
|
||||
|
||||
启用协议探测。
|
||||
|
||||
参阅 [协议探测](/zh/configuration/route/sniff/)。
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
用探测出的域名覆盖连接目标地址。
|
||||
|
||||
如果域名无效(如 Tor),将不生效。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,请求的域名将在路由之前解析为 IP。
|
||||
|
||||
如果 `sniff_override_destination` 生效,它的值将作为后备。
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
|
||||
|
||||
@@ -8,8 +8,8 @@ sing-box uses JSON for configuration files.
|
||||
{
|
||||
"log": {},
|
||||
"dns": {},
|
||||
"inbounds": [],
|
||||
"outbounds": [],
|
||||
"inbounds": {},
|
||||
"outbounds": {},
|
||||
"route": {},
|
||||
"experimental": {}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ sing-box 使用 JSON 作为配置文件格式。
|
||||
{
|
||||
"log": {},
|
||||
"dns": {},
|
||||
"inbounds": [],
|
||||
"outbounds": [],
|
||||
"inbounds": {},
|
||||
"outbounds": {},
|
||||
"route": {},
|
||||
"experimental": {}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# Log
|
||||
|
||||
### Structure
|
||||
|
||||
```json
|
||||
@@ -1,5 +1,3 @@
|
||||
# 日志
|
||||
|
||||
### 结构
|
||||
|
||||
```json
|
||||
@@ -4,8 +4,12 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "block",
|
||||
"tag": "block"
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "block",
|
||||
"tag": "block"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -4,8 +4,12 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "block",
|
||||
"tag": "block"
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "block",
|
||||
"tag": "block"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -4,18 +4,30 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct-out",
|
||||
|
||||
"override_address": "1.0.0.1",
|
||||
"override_port": 53,
|
||||
"proxy_protocol": 0,
|
||||
|
||||
... // Dial Fields
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct-out",
|
||||
|
||||
"override_address": "1.0.0.1",
|
||||
"override_port": 53,
|
||||
"proxy_protocol": 0,
|
||||
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
### Direct Fields
|
||||
|
||||
#### override_address
|
||||
|
||||
@@ -33,4 +45,54 @@ Protocol value can be `1` or `2`.
|
||||
|
||||
### Dial Fields
|
||||
|
||||
See [Dial Fields](/configuration/shared/dial) for details.
|
||||
#### detour
|
||||
|
||||
The tag of the upstream outbound.
|
||||
|
||||
Other dial fields will be ignored when enabled.
|
||||
|
||||
#### bind_interface
|
||||
|
||||
The network interface to bind to.
|
||||
|
||||
#### bind_address
|
||||
|
||||
The address to bind to.
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux.
|
||||
|
||||
Set netfilter routing mark.
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
Reuse listener address.
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
Connect timeout, in golang's Duration format.
|
||||
|
||||
A duration string is a possibly signed sequence of
|
||||
decimal numbers, each with optional fraction and a unit suffix,
|
||||
such as "300ms", "-1.5h" or "2h45m".
|
||||
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the requested domain name will be resolved to IP before connect.
|
||||
|
||||
`dns.strategy` will be used if empty.
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
|
||||
That is, is the amount of time to wait for IPv6 to succeed before assuming
|
||||
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
|
||||
If zero, a default delay of 300ms is used.
|
||||
|
||||
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
|
||||
@@ -4,18 +4,30 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct-out",
|
||||
|
||||
"override_address": "1.0.0.1",
|
||||
"override_port": 53,
|
||||
"proxy_protocol": 0,
|
||||
|
||||
... // 拨号字段
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct-out",
|
||||
|
||||
"override_address": "1.0.0.1",
|
||||
"override_port": 53,
|
||||
"proxy_protocol": 0,
|
||||
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 字段
|
||||
### Direct 字段
|
||||
|
||||
#### override_address
|
||||
|
||||
@@ -33,4 +45,51 @@
|
||||
|
||||
### 拨号字段
|
||||
|
||||
参阅 [拨号字段](/zh/configuration/shared/dial/)。
|
||||
#### detour
|
||||
|
||||
上游出站的标签。
|
||||
|
||||
启用时,其他拨号字段将被忽略。
|
||||
|
||||
#### bind_interface
|
||||
|
||||
要绑定到的网络接口。
|
||||
|
||||
#### bind_address
|
||||
|
||||
要绑定的地址。
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
仅支持 Linux。
|
||||
|
||||
设置 netfilter 路由标记。
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
重用监听地址。
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
连接超时,采用 golang 的 Duration 格式。
|
||||
|
||||
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
|
||||
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,域名将在请求发出之前解析为 IP。
|
||||
|
||||
默认使用 `dns.strategy`。
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
在生成 RFC 6555 快速回退连接之前等待的时间长度。
|
||||
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
|
||||
如果为零,则使用 300 毫秒的默认延迟。
|
||||
|
||||
仅当 `domain_strategy` 为 `prefer_ipv4` 或 `prefer_ipv6` 时生效。
|
||||
|
||||
@@ -4,8 +4,12 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "dns",
|
||||
"tag": "dns-out"
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "dns",
|
||||
"tag": "dns-out"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -4,8 +4,12 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "dns",
|
||||
"tag": "dns-out"
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "dns",
|
||||
"tag": "dns-out"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -4,20 +4,32 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"tag": "http-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"username": "sekai",
|
||||
"password": "admin",
|
||||
"tls": {},
|
||||
|
||||
... // Dial Fields
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "http",
|
||||
"tag": "http-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"username": "sekai",
|
||||
"password": "admin",
|
||||
"tls": {},
|
||||
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
### HTTP Fields
|
||||
|
||||
#### server
|
||||
|
||||
@@ -45,4 +57,54 @@ TLS configuration, see [TLS](/configuration/shared/tls/#outbound).
|
||||
|
||||
### Dial Fields
|
||||
|
||||
See [Dial Fields](/configuration/shared/dial) for details.
|
||||
#### detour
|
||||
|
||||
The tag of the upstream outbound.
|
||||
|
||||
Other dial fields will be ignored when enabled.
|
||||
|
||||
#### bind_interface
|
||||
|
||||
The network interface to bind to.
|
||||
|
||||
#### bind_address
|
||||
|
||||
The address to bind to.
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux.
|
||||
|
||||
Set netfilter routing mark.
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
Reuse listener address.
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
Connect timeout, in golang's Duration format.
|
||||
|
||||
A duration string is a possibly signed sequence of
|
||||
decimal numbers, each with optional fraction and a unit suffix,
|
||||
such as "300ms", "-1.5h" or "2h45m".
|
||||
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the server domain name will be resolved to IP before connecting.
|
||||
|
||||
`dns.strategy` will be used if empty.
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
|
||||
That is, is the amount of time to wait for IPv6 to succeed before assuming
|
||||
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
|
||||
If zero, a default delay of 300ms is used.
|
||||
|
||||
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
|
||||
@@ -4,20 +4,32 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"tag": "http-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"username": "sekai",
|
||||
"password": "admin",
|
||||
"tls": {},
|
||||
|
||||
... // 拨号字段
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "http",
|
||||
"tag": "http-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"username": "sekai",
|
||||
"password": "admin",
|
||||
"tls": {},
|
||||
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 字段
|
||||
### HTTP 字段
|
||||
|
||||
#### server
|
||||
|
||||
@@ -45,4 +57,51 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#outbound)。
|
||||
|
||||
### 拨号字段
|
||||
|
||||
参阅 [拨号字段](/zh/configuration/shared/dial/)。
|
||||
#### detour
|
||||
|
||||
上游出站的标签。
|
||||
|
||||
启用时,其他拨号字段将被忽略。
|
||||
|
||||
#### bind_interface
|
||||
|
||||
要绑定到的网络接口。
|
||||
|
||||
#### bind_address
|
||||
|
||||
要绑定的地址。
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
仅支持 Linux。
|
||||
|
||||
设置 netfilter 路由标记。
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
重用监听地址。
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
连接超时,采用 golang 的 Duration 格式。
|
||||
|
||||
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
|
||||
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,服务器域名将在连接前解析为 IP。
|
||||
|
||||
默认使用 `dns.strategy`。
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
在生成 RFC 6555 快速回退连接之前等待的时间长度。
|
||||
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
|
||||
如果为零,则使用 300 毫秒的默认延迟。
|
||||
|
||||
仅当 `domain_strategy` 为 `prefer_ipv4` 或 `prefer_ipv6` 时生效。
|
||||
|
||||
@@ -2,25 +2,37 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "hysteria",
|
||||
"tag": "hysteria-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"up": "100 Mbps",
|
||||
"up_mbps": 100,
|
||||
"down": "100 Mbps",
|
||||
"down_mbps": 100,
|
||||
"obfs": "fuck me till the daylight",
|
||||
"auth": "",
|
||||
"auth_str": "password",
|
||||
"recv_window_conn": 0,
|
||||
"recv_window": 0,
|
||||
"disable_mtu_discovery": false,
|
||||
"network": "tcp",
|
||||
"tls": {},
|
||||
|
||||
... // Dial Fields
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "hysteria",
|
||||
"tag": "hysteria-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
|
||||
"up": "100 Mbps",
|
||||
"up_mbps": 100,
|
||||
"down": "100 Mbps",
|
||||
"down_mbps": 100,
|
||||
"obfs": "fuck me till the daylight",
|
||||
"auth": "",
|
||||
"auth_str": "password",
|
||||
"recv_window_conn": 0,
|
||||
"recv_window": 0,
|
||||
"disable_mtu_discovery": false,
|
||||
"network": "tcp",
|
||||
"tls": {},
|
||||
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -28,7 +40,7 @@
|
||||
|
||||
QUIC, which is required by hysteria is not included by default, see [Installation](/#installation).
|
||||
|
||||
### Fields
|
||||
### Hysteria Fields
|
||||
|
||||
#### server
|
||||
|
||||
@@ -113,4 +125,54 @@ Both is enabled by default.
|
||||
|
||||
### Dial Fields
|
||||
|
||||
See [Dial Fields](/configuration/shared/dial) for details.
|
||||
#### detour
|
||||
|
||||
The tag of the upstream outbound.
|
||||
|
||||
Other dial fields will be ignored when enabled.
|
||||
|
||||
#### bind_interface
|
||||
|
||||
The network interface to bind to.
|
||||
|
||||
#### bind_address
|
||||
|
||||
The address to bind to.
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux.
|
||||
|
||||
Set netfilter routing mark.
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
Reuse listener address.
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
Connect timeout, in golang's Duration format.
|
||||
|
||||
A duration string is a possibly signed sequence of
|
||||
decimal numbers, each with optional fraction and a unit suffix,
|
||||
such as "300ms", "-1.5h" or "2h45m".
|
||||
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the server domain name will be resolved to IP before connecting.
|
||||
|
||||
`dns.strategy` will be used if empty.
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
|
||||
That is, is the amount of time to wait for IPv6 to succeed before assuming
|
||||
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
|
||||
If zero, a default delay of 300ms is used.
|
||||
|
||||
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
|
||||
@@ -2,25 +2,37 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "hysteria",
|
||||
"tag": "hysteria-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"up": "100 Mbps",
|
||||
"up_mbps": 100,
|
||||
"down": "100 Mbps",
|
||||
"down_mbps": 100,
|
||||
"obfs": "fuck me till the daylight",
|
||||
"auth": "",
|
||||
"auth_str": "password",
|
||||
"recv_window_conn": 0,
|
||||
"recv_window": 0,
|
||||
"disable_mtu_discovery": false,
|
||||
"network": "tcp",
|
||||
"tls": {},
|
||||
|
||||
... // 拨号字段
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "hysteria",
|
||||
"tag": "hysteria-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
|
||||
"up": "100 Mbps",
|
||||
"up_mbps": 100,
|
||||
"down": "100 Mbps",
|
||||
"down_mbps": 100,
|
||||
"obfs": "fuck me till the daylight",
|
||||
"auth": "",
|
||||
"auth_str": "password",
|
||||
"recv_window_conn": 0,
|
||||
"recv_window": 0,
|
||||
"disable_mtu_discovery": false,
|
||||
"network": "tcp",
|
||||
"tls": {},
|
||||
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -28,7 +40,7 @@
|
||||
|
||||
默认安装不包含被 Hysteria 依赖的 QUIC,参阅 [安装](/zh/#_2)。
|
||||
|
||||
### 字段
|
||||
### Hysteria 字段
|
||||
|
||||
#### server
|
||||
|
||||
@@ -111,4 +123,51 @@ TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#outbound)。
|
||||
|
||||
### 拨号字段
|
||||
|
||||
参阅 [拨号字段](/zh/configuration/shared/dial/)。
|
||||
#### detour
|
||||
|
||||
上游出站的标签。
|
||||
|
||||
启用时,其他拨号字段将被忽略。
|
||||
|
||||
#### bind_interface
|
||||
|
||||
要绑定到的网络接口。
|
||||
|
||||
#### bind_address
|
||||
|
||||
要绑定的地址。
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
仅支持 Linux。
|
||||
|
||||
设置 netfilter 路由标记。
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
重用监听地址
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
连接超时,采用 golang 的 Duration 格式。
|
||||
|
||||
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
|
||||
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,服务器域名将在连接前解析为 IP。
|
||||
|
||||
默认使用 `dns.strategy`。
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
在生成 RFC 6555 快速回退连接之前等待的时间长度。
|
||||
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
|
||||
如果为零,则使用 300 毫秒的默认延迟。
|
||||
|
||||
仅当 `domain_strategy` 为 `prefer_ipv4` 或 `prefer_ipv6` 时生效。
|
||||
|
||||
@@ -2,15 +2,19 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "selector",
|
||||
"tag": "select",
|
||||
|
||||
"outbounds": [
|
||||
"proxy-a",
|
||||
"proxy-b",
|
||||
"proxy-c"
|
||||
],
|
||||
"default": "proxy-c"
|
||||
{
|
||||
"type": "selector",
|
||||
"tag": "select",
|
||||
|
||||
"outbounds": [
|
||||
"proxy-a",
|
||||
"proxy-b",
|
||||
"proxy-c"
|
||||
],
|
||||
"default": "proxy-c"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -2,15 +2,19 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "selector",
|
||||
"tag": "select",
|
||||
|
||||
"outbounds": [
|
||||
"proxy-a",
|
||||
"proxy-b",
|
||||
"proxy-c"
|
||||
],
|
||||
"default": "proxy-c"
|
||||
{
|
||||
"type": "selector",
|
||||
"tag": "select",
|
||||
|
||||
"outbounds": [
|
||||
"proxy-a",
|
||||
"proxy-b",
|
||||
"proxy-c"
|
||||
],
|
||||
"default": "proxy-c"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -2,22 +2,34 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "shadowsocks",
|
||||
"tag": "ss-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"network": "udp",
|
||||
"udp_over_tcp": false,
|
||||
"multiplex": {},
|
||||
|
||||
... // Dial Fields
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "shadowsocks",
|
||||
"tag": "ss-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"network": "udp",
|
||||
"udp_over_tcp": false,
|
||||
"multiplex": {},
|
||||
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
### Shadowsocks Fields
|
||||
|
||||
#### server
|
||||
|
||||
@@ -85,4 +97,54 @@ Multiplex configuration, see [Multiplex](/configuration/shared/multiplex).
|
||||
|
||||
### Dial Fields
|
||||
|
||||
See [Dial Fields](/configuration/shared/dial) for details.
|
||||
#### detour
|
||||
|
||||
The tag of the upstream outbound.
|
||||
|
||||
Other dial fields will be ignored when enabled.
|
||||
|
||||
#### bind_interface
|
||||
|
||||
The network interface to bind to.
|
||||
|
||||
#### bind_address
|
||||
|
||||
The address to bind to.
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux.
|
||||
|
||||
Set netfilter routing mark.
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
Reuse listener address.
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
Connect timeout, in golang's Duration format.
|
||||
|
||||
A duration string is a possibly signed sequence of
|
||||
decimal numbers, each with optional fraction and a unit suffix,
|
||||
such as "300ms", "-1.5h" or "2h45m".
|
||||
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the server domain name will be resolved to IP before connecting.
|
||||
|
||||
`dns.strategy` will be used if empty.
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
|
||||
That is, is the amount of time to wait for IPv6 to succeed before assuming
|
||||
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
|
||||
If zero, a default delay of 300ms is used.
|
||||
|
||||
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
|
||||
@@ -1,23 +1,35 @@
|
||||
### 结构
|
||||
### Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "shadowsocks",
|
||||
"tag": "ss-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"network": "udp",
|
||||
"udp_over_tcp": false,
|
||||
"multiplex": {},
|
||||
|
||||
... // 拨号字段
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "shadowsocks",
|
||||
"tag": "ss-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"network": "udp",
|
||||
"udp_over_tcp": false,
|
||||
"multiplex": {},
|
||||
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 字段
|
||||
### Shadowsocks 字段
|
||||
|
||||
#### server
|
||||
|
||||
@@ -85,4 +97,51 @@ Shadowsocks 密码。
|
||||
|
||||
### 拨号字段
|
||||
|
||||
参阅 [拨号字段](/zh/configuration/shared/dial/)。
|
||||
#### detour
|
||||
|
||||
上游出站的标签。
|
||||
|
||||
启用时,其他拨号字段将被忽略。
|
||||
|
||||
#### bind_interface
|
||||
|
||||
要绑定到的网络接口。
|
||||
|
||||
#### bind_address
|
||||
|
||||
要绑定的地址。
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
仅支持 Linux。
|
||||
|
||||
设置 netfilter 路由标记。
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
重用监听地址。
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
连接超时,采用 golang 的 Duration 格式。
|
||||
|
||||
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
|
||||
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,服务器域名将在连接前解析为 IP。
|
||||
|
||||
默认使用 `dns.strategy`。
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
在生成 RFC 6555 快速回退连接之前等待的时间长度。
|
||||
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
|
||||
如果为零,则使用 300 毫秒的默认延迟。
|
||||
|
||||
仅当 `domain_strategy` 为 `prefer_ipv4` 或 `prefer_ipv6` 时生效。
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
### Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "shadowtls",
|
||||
"tag": "st-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"tls": {},
|
||||
|
||||
... // Dial Fields
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
|
||||
#### server
|
||||
|
||||
==Required==
|
||||
|
||||
The server address.
|
||||
|
||||
#### server_port
|
||||
|
||||
==Required==
|
||||
|
||||
The server port.
|
||||
|
||||
#### tls
|
||||
|
||||
==Required==
|
||||
|
||||
TLS configuration, see [TLS](/configuration/shared/tls/#outbound).
|
||||
|
||||
### Dial Fields
|
||||
|
||||
See [Dial Fields](/configuration/shared/dial) for details.
|
||||
@@ -1,38 +0,0 @@
|
||||
### 结构
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "shadowtls",
|
||||
"tag": "st-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"tls": {},
|
||||
|
||||
... // 拨号字段
|
||||
}
|
||||
```
|
||||
|
||||
### 字段
|
||||
|
||||
#### server
|
||||
|
||||
==必填==
|
||||
|
||||
服务器地址。
|
||||
|
||||
#### server_port
|
||||
|
||||
==必填==
|
||||
|
||||
服务器端口。
|
||||
|
||||
#### tls
|
||||
|
||||
==必填==
|
||||
|
||||
TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#outbound)。
|
||||
|
||||
### 拨号字段
|
||||
|
||||
参阅 [拨号字段](/zh/configuration/shared/dial/)。
|
||||
@@ -4,22 +4,34 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "socks-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"version": "5",
|
||||
"username": "sekai",
|
||||
"password": "admin",
|
||||
"network": "udp",
|
||||
"udp_over_tcp": false,
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "socks-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"version": "5",
|
||||
"username": "sekai",
|
||||
"password": "admin",
|
||||
"network": "udp",
|
||||
"udp_over_tcp": false,
|
||||
|
||||
... // Dial Fields
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
### SOCKS Fields
|
||||
|
||||
#### server
|
||||
|
||||
@@ -61,4 +73,54 @@ Enable the UDP over TCP protocol.
|
||||
|
||||
### Dial Fields
|
||||
|
||||
See [Dial Fields](/configuration/shared/dial) for details.
|
||||
#### detour
|
||||
|
||||
The tag of the upstream outbound.
|
||||
|
||||
Other dial fields will be ignored when enabled.
|
||||
|
||||
#### bind_interface
|
||||
|
||||
The network interface to bind to.
|
||||
|
||||
#### bind_address
|
||||
|
||||
The address to bind to.
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux.
|
||||
|
||||
Set netfilter routing mark.
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
Reuse listener address.
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
Connect timeout, in golang's Duration format.
|
||||
|
||||
A duration string is a possibly signed sequence of
|
||||
decimal numbers, each with optional fraction and a unit suffix,
|
||||
such as "300ms", "-1.5h" or "2h45m".
|
||||
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the server domain name will be resolved to IP before connecting.
|
||||
|
||||
`dns.strategy` will be used if empty.
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
|
||||
That is, is the amount of time to wait for IPv6 to succeed before assuming
|
||||
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
|
||||
If zero, a default delay of 300ms is used.
|
||||
|
||||
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
`socks` 出站是 socks4/socks4a/socks5 客户端
|
||||
|
||||
### 结构
|
||||
### Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "socks-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"version": "5",
|
||||
"username": "sekai",
|
||||
"password": "admin",
|
||||
"network": "udp",
|
||||
"udp_over_tcp": false,
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "socks-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"version": "5",
|
||||
"username": "sekai",
|
||||
"password": "admin",
|
||||
"network": "udp",
|
||||
"udp_over_tcp": false,
|
||||
|
||||
... // 拨号字段
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 字段
|
||||
### SOCKS 字段
|
||||
|
||||
#### server
|
||||
|
||||
@@ -61,4 +73,51 @@ SOCKS5 密码。
|
||||
|
||||
### 拨号字段
|
||||
|
||||
参阅 [拨号字段](/zh/configuration/shared/dial/)。
|
||||
#### detour
|
||||
|
||||
上游出站的标签。
|
||||
|
||||
启用时,其他拨号字段将被忽略。
|
||||
|
||||
#### bind_interface
|
||||
|
||||
要绑定到的网络接口。
|
||||
|
||||
#### bind_address
|
||||
|
||||
要绑定的地址。
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
仅支持 Linux。
|
||||
|
||||
设置 netfilter 路由标记。
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
重用监听地址。
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
连接超时,采用 golang 的 Duration 格式。
|
||||
|
||||
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
|
||||
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,服务器域名将在连接前解析为 IP。
|
||||
|
||||
默认使用 `dns.strategy`。
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
在生成 RFC 6555 快速回退连接之前等待的时间长度。
|
||||
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
|
||||
如果为零,则使用 300 毫秒的默认延迟。
|
||||
|
||||
仅当 `domain_strategy` 为 `prefer_ipv4` 或 `prefer_ipv6` 时生效。
|
||||
|
||||
@@ -2,24 +2,36 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ssh",
|
||||
"tag": "ssh-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 22,
|
||||
"user": "root",
|
||||
"password": "admin",
|
||||
"private_key": "",
|
||||
"private_key_path": "$HOME/.ssh/id_rsa",
|
||||
"private_key_passphrase": "",
|
||||
"host_key_algorithms": [],
|
||||
"client_version": "SSH-2.0-OpenSSH_7.4p1",
|
||||
|
||||
... // Dial Fields
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "ssh",
|
||||
"tag": "ssh-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 22,
|
||||
"user": "root",
|
||||
"password": "admin",
|
||||
"private_key": "",
|
||||
"private_key_path": "$HOME/.ssh/id_rsa",
|
||||
"private_key_passphrase": "",
|
||||
"host_key_algorithms": [],
|
||||
"client_version": "SSH-2.0-OpenSSH_7.4p1",
|
||||
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
### SSH Fields
|
||||
|
||||
#### server
|
||||
|
||||
@@ -61,4 +73,54 @@ Client version. Random version will be used if empty.
|
||||
|
||||
### Dial Fields
|
||||
|
||||
See [Dial Fields](/configuration/shared/dial) for details.
|
||||
#### detour
|
||||
|
||||
The tag of the upstream outbound.
|
||||
|
||||
Other dial fields will be ignored when enabled.
|
||||
|
||||
#### bind_interface
|
||||
|
||||
The network interface to bind to.
|
||||
|
||||
#### bind_address
|
||||
|
||||
The address to bind to.
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux.
|
||||
|
||||
Set netfilter routing mark.
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
Reuse listener address.
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
Connect timeout, in golang's Duration format.
|
||||
|
||||
A duration string is a possibly signed sequence of
|
||||
decimal numbers, each with optional fraction and a unit suffix,
|
||||
such as "300ms", "-1.5h" or "2h45m".
|
||||
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the server domain name will be resolved to IP before connecting.
|
||||
|
||||
`dns.strategy` will be used if empty.
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
|
||||
That is, is the amount of time to wait for IPv6 to succeed before assuming
|
||||
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
|
||||
If zero, a default delay of 300ms is used.
|
||||
|
||||
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
### 结构
|
||||
### Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ssh",
|
||||
"tag": "ssh-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 22,
|
||||
"user": "root",
|
||||
"password": "admin",
|
||||
"private_key": "",
|
||||
"private_key_path": "$HOME/.ssh/id_rsa",
|
||||
"private_key_passphrase": "",
|
||||
"host_key_algorithms": [],
|
||||
"client_version": "SSH-2.0-OpenSSH_7.4p1",
|
||||
|
||||
... // 拨号字段
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "ssh",
|
||||
"tag": "ssh-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 22,
|
||||
"user": "root",
|
||||
"password": "admin",
|
||||
"private_key": "",
|
||||
"private_key_path": "$HOME/.ssh/id_rsa",
|
||||
"private_key_passphrase": "",
|
||||
"host_key_algorithms": [],
|
||||
"client_version": "SSH-2.0-OpenSSH_7.4p1",
|
||||
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 字段
|
||||
### SSH 字段
|
||||
|
||||
#### server
|
||||
|
||||
@@ -61,4 +73,51 @@ SSH 用户, 默认使用 root。
|
||||
|
||||
### 拨号字段
|
||||
|
||||
参阅 [拨号字段](/zh/configuration/shared/dial/)。
|
||||
#### detour
|
||||
|
||||
上游出站的标签。
|
||||
|
||||
启用时,其他拨号字段将被忽略。
|
||||
|
||||
#### bind_interface
|
||||
|
||||
要绑定到的网络接口。
|
||||
|
||||
#### bind_address
|
||||
|
||||
要绑定的地址。
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
仅支持 Linux。
|
||||
|
||||
设置 netfilter 路由标记。
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
重用监听地址。
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
连接超时,采用 golang 的 Duration 格式。
|
||||
|
||||
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
|
||||
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,服务器域名将在连接前解析为 IP。
|
||||
|
||||
默认使用 `dns.strategy`。
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
在生成 RFC 6555 快速回退连接之前等待的时间长度。
|
||||
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
|
||||
如果为零,则使用 300 毫秒的默认延迟。
|
||||
|
||||
仅当 `domain_strategy` 为 `prefer_ipv4` 或 `prefer_ipv6` 时生效。
|
||||
|
||||
@@ -2,17 +2,29 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "tor",
|
||||
"tag": "tor-out",
|
||||
|
||||
"executable_path": "/usr/bin/tor",
|
||||
"extra_args": [],
|
||||
"data_directory": "$HOME/.cache/tor",
|
||||
"torrc": {
|
||||
"ClientOnly": 1
|
||||
},
|
||||
|
||||
... // Dial Fields
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "tor",
|
||||
"tag": "tor-out",
|
||||
|
||||
"executable_path": "/usr/bin/tor",
|
||||
"extra_args": [],
|
||||
"data_directory": "$HOME/.cache/tor",
|
||||
"torrc": {
|
||||
"ClientOnly": 1
|
||||
},
|
||||
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -20,7 +32,7 @@
|
||||
|
||||
Embedded tor is not included by default, see [Installation](/#installation).
|
||||
|
||||
### Fields
|
||||
### Tor Fields
|
||||
|
||||
#### executable_path
|
||||
|
||||
@@ -44,8 +56,58 @@ Each start will be very slow if not specified.
|
||||
|
||||
Map of torrc options.
|
||||
|
||||
See [tor(1)](https://linux.die.net/man/1/tor) for details.
|
||||
See [tor(1)](https://linux.die.net/man/1/tor)
|
||||
|
||||
### Dial Fields
|
||||
|
||||
See [Dial Fields](/configuration/shared/dial) for details.
|
||||
#### detour
|
||||
|
||||
The tag of the upstream outbound.
|
||||
|
||||
Other dial fields will be ignored when enabled.
|
||||
|
||||
#### bind_interface
|
||||
|
||||
The network interface to bind to.
|
||||
|
||||
#### bind_address
|
||||
|
||||
The address to bind to.
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux.
|
||||
|
||||
Set netfilter routing mark.
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
Reuse listener address.
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
Connect timeout, in golang's Duration format.
|
||||
|
||||
A duration string is a possibly signed sequence of
|
||||
decimal numbers, each with optional fraction and a unit suffix,
|
||||
such as "300ms", "-1.5h" or "2h45m".
|
||||
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the server domain name will be resolved to IP before connecting.
|
||||
|
||||
`dns.strategy` will be used if empty.
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
|
||||
That is, is the amount of time to wait for IPv6 to succeed before assuming
|
||||
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
|
||||
If zero, a default delay of 300ms is used.
|
||||
|
||||
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
|
||||
@@ -2,17 +2,29 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "tor",
|
||||
"tag": "tor-out",
|
||||
|
||||
"executable_path": "/usr/bin/tor",
|
||||
"extra_args": [],
|
||||
"data_directory": "$HOME/.cache/tor",
|
||||
"torrc": {
|
||||
"ClientOnly": 1
|
||||
},
|
||||
|
||||
... // 拨号字段
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "tor",
|
||||
"tag": "tor-out",
|
||||
|
||||
"executable_path": "/usr/bin/tor",
|
||||
"extra_args": [],
|
||||
"data_directory": "$HOME/.cache/tor",
|
||||
"torrc": {
|
||||
"ClientOnly": 1
|
||||
},
|
||||
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -20,7 +32,7 @@
|
||||
|
||||
默认安装不包含嵌入式 Tor, 参阅 [安装](/zh/#_2)。
|
||||
|
||||
### 字段
|
||||
### Tor 字段
|
||||
|
||||
#### executable_path
|
||||
|
||||
@@ -48,4 +60,51 @@ torrc 参数表。
|
||||
|
||||
### 拨号字段
|
||||
|
||||
参阅 [拨号字段](/zh/configuration/shared/dial/)。
|
||||
#### detour
|
||||
|
||||
上游出站的标签。
|
||||
|
||||
启用时,其他拨号字段将被忽略。
|
||||
|
||||
#### bind_interface
|
||||
|
||||
要绑定到的网络接口。
|
||||
|
||||
#### bind_address
|
||||
|
||||
要绑定的地址。
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
仅支持 Linux。
|
||||
|
||||
设置 netfilter 路由标记。
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
重用监听地址。
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
连接超时,采用 golang 的 Duration 格式。
|
||||
|
||||
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
|
||||
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,服务器域名将在连接前解析为 IP。
|
||||
|
||||
默认使用 `dns.strategy`。
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
在生成 RFC 6555 快速回退连接之前等待的时间长度。
|
||||
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
|
||||
如果为零,则使用 300 毫秒的默认延迟。
|
||||
|
||||
仅当 `domain_strategy` 为 `prefer_ipv4` 或 `prefer_ipv6` 时生效。
|
||||
|
||||
@@ -2,22 +2,34 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "trojan",
|
||||
"tag": "trojan-out",
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "trojan",
|
||||
"tag": "trojan-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"network": "tcp",
|
||||
"tls": {},
|
||||
"multiplex": {},
|
||||
"transport": {},
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"network": "tcp",
|
||||
"tls": {},
|
||||
"multiplex": {},
|
||||
"transport": {},
|
||||
|
||||
... // Dial Fields
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
### Trojan Fields
|
||||
|
||||
#### server
|
||||
|
||||
@@ -59,4 +71,54 @@ V2Ray Transport configuration, see [V2Ray Transport](/configuration/shared/v2ray
|
||||
|
||||
### Dial Fields
|
||||
|
||||
See [Dial Fields](/configuration/shared/dial) for details.
|
||||
#### detour
|
||||
|
||||
The tag of the upstream outbound.
|
||||
|
||||
Other dial fields will be ignored when enabled.
|
||||
|
||||
#### bind_interface
|
||||
|
||||
The network interface to bind to.
|
||||
|
||||
#### bind_address
|
||||
|
||||
The address to bind to.
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux.
|
||||
|
||||
Set netfilter routing mark.
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
Reuse listener address.
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
Connect timeout, in golang's Duration format.
|
||||
|
||||
A duration string is a possibly signed sequence of
|
||||
decimal numbers, each with optional fraction and a unit suffix,
|
||||
such as "300ms", "-1.5h" or "2h45m".
|
||||
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the server domain name will be resolved to IP before connecting.
|
||||
|
||||
`dns.strategy` will be used if empty.
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
|
||||
That is, is the amount of time to wait for IPv6 to succeed before assuming
|
||||
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
|
||||
If zero, a default delay of 300ms is used.
|
||||
|
||||
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
|
||||
@@ -2,22 +2,34 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "trojan",
|
||||
"tag": "trojan-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"network": "tcp",
|
||||
"tls": {},
|
||||
"multiplex": {},
|
||||
"transport": {},
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "trojan",
|
||||
"tag": "trojan-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"network": "tcp",
|
||||
"tls": {},
|
||||
"multiplex": {},
|
||||
"transport": {},
|
||||
|
||||
... // 拨号字段
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 字段
|
||||
### Trojan 字段
|
||||
|
||||
#### server
|
||||
|
||||
@@ -59,4 +71,51 @@ V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-tra
|
||||
|
||||
### 拨号字段
|
||||
|
||||
参阅 [拨号字段](/zh/configuration/shared/dial/)。
|
||||
#### detour
|
||||
|
||||
上游出站的标签。
|
||||
|
||||
启用时,其他拨号字段将被忽略。
|
||||
|
||||
#### bind_interface
|
||||
|
||||
要绑定到的网络接口。
|
||||
|
||||
#### bind_address
|
||||
|
||||
要绑定的地址。
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
仅支持 Linux。
|
||||
|
||||
设置 netfilter 路由标记。
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
重用监听地址。
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
连接超时,采用 golang 的 Duration 格式。
|
||||
|
||||
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
|
||||
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,服务器域名将在连接前解析为 IP。
|
||||
|
||||
默认使用 `dns.strategy`。
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
在生成 RFC 6555 快速回退连接之前等待的时间长度。
|
||||
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
|
||||
如果为零,则使用 300 毫秒的默认延迟。
|
||||
|
||||
仅当 `domain_strategy` 为 `prefer_ipv4` 或 `prefer_ipv6` 时生效。
|
||||
|
||||
@@ -2,27 +2,39 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "vmess",
|
||||
"tag": "vmess-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
|
||||
"security": "auto",
|
||||
"alter_id": 0,
|
||||
"global_padding": false,
|
||||
"authenticated_length": true,
|
||||
"network": "tcp",
|
||||
"tls": {},
|
||||
"packet_addr": false,
|
||||
"multiplex": {},
|
||||
"transport": {},
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "vmess",
|
||||
"tag": "vmess-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
|
||||
"security": "auto",
|
||||
"alter_id": 0,
|
||||
"global_padding": false,
|
||||
"authenticated_length": true,
|
||||
"network": "tcp",
|
||||
"tls": {},
|
||||
"packet_addr": false,
|
||||
"multiplex": {},
|
||||
"transport": {},
|
||||
|
||||
... // Dial Fields
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
### VMess Fields
|
||||
|
||||
#### server
|
||||
|
||||
@@ -98,4 +110,54 @@ V2Ray Transport configuration, see [V2Ray Transport](/configuration/shared/v2ray
|
||||
|
||||
### Dial Fields
|
||||
|
||||
See [Dial Fields](/configuration/shared/dial) for details.
|
||||
#### detour
|
||||
|
||||
The tag of the upstream outbound.
|
||||
|
||||
Other dial fields will be ignored when enabled.
|
||||
|
||||
#### bind_interface
|
||||
|
||||
The network interface to bind to.
|
||||
|
||||
#### bind_address
|
||||
|
||||
The address to bind to.
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux.
|
||||
|
||||
Set netfilter routing mark.
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
Reuse listener address.
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
Connect timeout, in golang's Duration format.
|
||||
|
||||
A duration string is a possibly signed sequence of
|
||||
decimal numbers, each with optional fraction and a unit suffix,
|
||||
such as "300ms", "-1.5h" or "2h45m".
|
||||
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the server domain name will be resolved to IP before connecting.
|
||||
|
||||
`dns.strategy` will be used if empty.
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
|
||||
That is, is the amount of time to wait for IPv6 to succeed before assuming
|
||||
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
|
||||
If zero, a default delay of 300ms is used.
|
||||
|
||||
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
|
||||
@@ -2,27 +2,39 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "vmess",
|
||||
"tag": "vmess-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
|
||||
"security": "auto",
|
||||
"alter_id": 0,
|
||||
"global_padding": false,
|
||||
"authenticated_length": true,
|
||||
"network": "tcp",
|
||||
"tls": {},
|
||||
"packet_addr": false,
|
||||
"multiplex": {},
|
||||
"transport": {},
|
||||
|
||||
... // 拨号字段
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "vmess",
|
||||
"tag": "vmess-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
|
||||
"security": "auto",
|
||||
"alter_id": 0,
|
||||
"global_padding": false,
|
||||
"authenticated_length": true,
|
||||
"network": "tcp",
|
||||
"tls": {},
|
||||
"packet_addr": false,
|
||||
"multiplex": {},
|
||||
"transport": {},
|
||||
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 字段
|
||||
### VMess 字段
|
||||
|
||||
#### server
|
||||
|
||||
@@ -98,4 +110,51 @@ V2Ray 传输配置,参阅 [V2Ray 传输层](/zh/configuration/shared/v2ray-tra
|
||||
|
||||
### 拨号字段
|
||||
|
||||
参阅 [拨号字段](/zh/configuration/shared/dial/)。
|
||||
#### detour
|
||||
|
||||
上游出站的标签。
|
||||
|
||||
启用时,其他拨号字段将被忽略。
|
||||
|
||||
#### bind_interface
|
||||
|
||||
要绑定到的网络接口。
|
||||
|
||||
#### bind_address
|
||||
|
||||
要绑定的地址。
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
仅支持 Linux。
|
||||
|
||||
设置 netfilter 路由标记。
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
重用监听地址。
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
连接超时,采用 golang 的 Duration 格式。
|
||||
|
||||
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
|
||||
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,服务器域名将在连接前解析为 IP。
|
||||
|
||||
默认使用 `dns.strategy`。
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
在生成 RFC 6555 快速回退连接之前等待的时间长度。
|
||||
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
|
||||
如果为零,则使用 300 毫秒的默认延迟。
|
||||
|
||||
仅当 `domain_strategy` 为 `prefer_ipv4` 或 `prefer_ipv6` 时生效。
|
||||
@@ -2,22 +2,34 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "wireguard",
|
||||
"tag": "wireguard-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"local_address": [
|
||||
"10.0.0.1",
|
||||
"10.0.0.2/32"
|
||||
],
|
||||
"private_key": "YNXtAzepDqRv9H52osJVDQnznT5AM11eCK3ESpwSt04=",
|
||||
"peer_public_key": "Z1XXLsKYkYxuiYjJIkRvtIKFepCYHTgON+GwPq7SOV4=",
|
||||
"pre_shared_key": "31aIhAPwktDGpH4JDhA8GNvjFXEf/a6+UaQRyOAiyfM=",
|
||||
"mtu": 1408,
|
||||
"network": "tcp",
|
||||
|
||||
... // Dial Fields
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "wireguard",
|
||||
"tag": "wireguard-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"local_address": [
|
||||
"10.0.0.1",
|
||||
"10.0.0.2/32"
|
||||
],
|
||||
"private_key": "YNXtAzepDqRv9H52osJVDQnznT5AM11eCK3ESpwSt04=",
|
||||
"peer_public_key": "Z1XXLsKYkYxuiYjJIkRvtIKFepCYHTgON+GwPq7SOV4=",
|
||||
"pre_shared_key": "31aIhAPwktDGpH4JDhA8GNvjFXEf/a6+UaQRyOAiyfM=",
|
||||
"mtu": 1408,
|
||||
"network": "tcp",
|
||||
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -25,7 +37,7 @@
|
||||
|
||||
WireGuard is not included by default, see [Installation](/#installation).
|
||||
|
||||
### Fields
|
||||
### WireGuard Fields
|
||||
|
||||
#### server
|
||||
|
||||
@@ -80,4 +92,54 @@ Both is enabled by default.
|
||||
|
||||
### Dial Fields
|
||||
|
||||
See [Dial Fields](/configuration/shared/dial) for details.
|
||||
#### detour
|
||||
|
||||
The tag of the upstream outbound.
|
||||
|
||||
Other dial fields will be ignored when enabled.
|
||||
|
||||
#### bind_interface
|
||||
|
||||
The network interface to bind to.
|
||||
|
||||
#### bind_address
|
||||
|
||||
The address to bind to.
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux.
|
||||
|
||||
Set netfilter routing mark.
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
Reuse listener address.
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
Connect timeout, in golang's Duration format.
|
||||
|
||||
A duration string is a possibly signed sequence of
|
||||
decimal numbers, each with optional fraction and a unit suffix,
|
||||
such as "300ms", "-1.5h" or "2h45m".
|
||||
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the server domain name will be resolved to IP before connecting.
|
||||
|
||||
`dns.strategy` will be used if empty.
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
|
||||
That is, is the amount of time to wait for IPv6 to succeed before assuming
|
||||
that IPv6 is misconfigured and falling back to IPv4 if `prefer_ipv4` is set.
|
||||
If zero, a default delay of 300ms is used.
|
||||
|
||||
Only take effect when `domain_strategy` is `prefer_ipv4` or `prefer_ipv6`.
|
||||
@@ -2,22 +2,34 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "wireguard",
|
||||
"tag": "wireguard-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"local_address": [
|
||||
"10.0.0.1",
|
||||
"10.0.0.2/32"
|
||||
],
|
||||
"private_key": "YNXtAzepDqRv9H52osJVDQnznT5AM11eCK3ESpwSt04=",
|
||||
"peer_public_key": "Z1XXLsKYkYxuiYjJIkRvtIKFepCYHTgON+GwPq7SOV4=",
|
||||
"pre_shared_key": "31aIhAPwktDGpH4JDhA8GNvjFXEf/a6+UaQRyOAiyfM=",
|
||||
"mtu": 1408,
|
||||
"network": "tcp",
|
||||
|
||||
... // 拨号字段
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "wireguard",
|
||||
"tag": "wireguard-out",
|
||||
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 1080,
|
||||
"local_address": [
|
||||
"10.0.0.1",
|
||||
"10.0.0.2/32"
|
||||
],
|
||||
"private_key": "YNXtAzepDqRv9H52osJVDQnznT5AM11eCK3ESpwSt04=",
|
||||
"peer_public_key": "Z1XXLsKYkYxuiYjJIkRvtIKFepCYHTgON+GwPq7SOV4=",
|
||||
"pre_shared_key": "31aIhAPwktDGpH4JDhA8GNvjFXEf/a6+UaQRyOAiyfM=",
|
||||
"mtu": 1408,
|
||||
"network": "tcp",
|
||||
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -25,7 +37,7 @@
|
||||
|
||||
默认安装不包含 WireGuard, 参阅 [安装](/zh/#_2)。
|
||||
|
||||
### 字段
|
||||
### WireGuard 字段
|
||||
|
||||
#### server
|
||||
|
||||
@@ -82,4 +94,51 @@ WireGuard MTU。 默认1408。
|
||||
|
||||
### 拨号字段
|
||||
|
||||
参阅 [拨号字段](/zh/configuration/shared/dial/)。
|
||||
#### detour
|
||||
|
||||
上游出站的标签。
|
||||
|
||||
启用时,其他拨号字段将被忽略。
|
||||
|
||||
#### bind_interface
|
||||
|
||||
要绑定到的网络接口。
|
||||
|
||||
#### bind_address
|
||||
|
||||
要绑定的地址。
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
仅支持 Linux。
|
||||
|
||||
设置 netfilter 路由标记。
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
重用监听地址。
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
连接超时,采用 golang 的 Duration 格式。
|
||||
|
||||
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
|
||||
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,服务器域名将在连接前解析为 IP。
|
||||
|
||||
默认使用 `dns.strategy`。
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
在生成 RFC 6555 快速回退连接之前等待的时间长度。
|
||||
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
|
||||
如果为零,则使用 300 毫秒的默认延迟。
|
||||
|
||||
仅当 `domain_strategy` 为 `prefer_ipv4` 或 `prefer_ipv6` 时生效。
|
||||
|
||||
@@ -68,9 +68,6 @@
|
||||
"process_name": [
|
||||
"curl"
|
||||
],
|
||||
"process_path": [
|
||||
"/usr/bin/curl"
|
||||
],
|
||||
"package_name": [
|
||||
"com.termux"
|
||||
],
|
||||
@@ -191,14 +188,6 @@ Match port range.
|
||||
|
||||
Match process name.
|
||||
|
||||
#### process_path
|
||||
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux, Windows, and macOS.
|
||||
|
||||
Match process path.
|
||||
|
||||
#### package_name
|
||||
|
||||
Match android package name.
|
||||
|
||||
@@ -66,9 +66,6 @@
|
||||
"process_name": [
|
||||
"curl"
|
||||
],
|
||||
"process_path": [
|
||||
"/usr/bin/curl"
|
||||
],
|
||||
"package_name": [
|
||||
"com.termux"
|
||||
],
|
||||
@@ -189,14 +186,6 @@
|
||||
|
||||
匹配进程名称。
|
||||
|
||||
#### process_path
|
||||
|
||||
!!! error ""
|
||||
|
||||
仅支持 Linux、Windows 和 macOS.
|
||||
|
||||
匹配进程路径。
|
||||
|
||||
#### package_name
|
||||
|
||||
匹配 Android 应用包名。
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
### Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
|
||||
| Field | Available Context |
|
||||
|-----------------------------------------------------------------------------------|-------------------|
|
||||
| `bind_interface` /`bind_address` /`routing_mark` /`reuse_addr` /`connect_timeout` | `detour` not set |
|
||||
|
||||
#### detour
|
||||
|
||||
The tag of the upstream outbound.
|
||||
|
||||
#### bind_interface
|
||||
|
||||
The network interface to bind to.
|
||||
|
||||
#### bind_address
|
||||
|
||||
The address to bind to.
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
Only supported on Linux.
|
||||
|
||||
Set netfilter routing mark.
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
Reuse listener address.
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
Connect timeout, in golang's Duration format.
|
||||
|
||||
A duration string is a possibly signed sequence of
|
||||
decimal numbers, each with optional fraction and a unit suffix,
|
||||
such as "300ms", "-1.5h" or "2h45m".
|
||||
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the requested domain name will be resolved to IP before connect.
|
||||
|
||||
| Outbound | Effected domains | Fallback Value |
|
||||
|----------|--------------------------|-------------------------------------------|
|
||||
| `direct` | Domain in request | Take `inbound.domain_strategy` if not set |
|
||||
| others | Domain in server address | / |
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
The length of time to wait before spawning a RFC 6555 Fast Fallback connection.
|
||||
That is, is the amount of time to wait for connection to succeed before assuming
|
||||
that IPv4/IPv6 is misconfigured and falling back to other type of addresses.
|
||||
If zero, a default delay of 300ms is used.
|
||||
|
||||
Only take effect when `domain_strategy` is set.
|
||||
@@ -1,66 +0,0 @@
|
||||
### 结构
|
||||
|
||||
```json
|
||||
{
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"bind_address": "0.0.0.0",
|
||||
"routing_mark": 1234,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"tcp_fast_open": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"fallback_delay": "300ms"
|
||||
}
|
||||
```
|
||||
|
||||
### 字段
|
||||
|
||||
#### detour
|
||||
|
||||
上游出站的标签。
|
||||
|
||||
启用时,其他拨号字段将被忽略。
|
||||
|
||||
#### bind_interface
|
||||
|
||||
要绑定到的网络接口。
|
||||
|
||||
#### bind_address
|
||||
|
||||
要绑定的地址。
|
||||
|
||||
#### routing_mark
|
||||
|
||||
!!! error ""
|
||||
|
||||
仅支持 Linux。
|
||||
|
||||
设置 netfilter 路由标记。
|
||||
|
||||
#### reuse_addr
|
||||
|
||||
重用监听地址。
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
连接超时,采用 golang 的 Duration 格式。
|
||||
|
||||
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
|
||||
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,域名将在请求发出之前解析为 IP。
|
||||
|
||||
默认使用 `dns.strategy`。
|
||||
|
||||
#### fallback_delay
|
||||
|
||||
在生成 RFC 6555 快速回退连接之前等待的时间长度。
|
||||
也就是说,是在假设之前等待 IPv6 成功的时间量如果设置了 "prefer_ipv4",则 IPv6 配置错误并回退到 IPv4。
|
||||
如果为零,则使用 300 毫秒的默认延迟。
|
||||
|
||||
仅当 `domain_strategy` 为 `prefer_ipv4` 或 `prefer_ipv6` 时生效。
|
||||
@@ -1,73 +0,0 @@
|
||||
### Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"listen": "::",
|
||||
"listen_port": 5353,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"udp_timeout": 300,
|
||||
"proxy_protocol": false,
|
||||
"detour": "another-in"
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
|
||||
| Field | Available Context |
|
||||
|------------------|-------------------------------------------------------------------|
|
||||
| `listen` | Needs to listen on TCP or UDP. |
|
||||
| `listen_port` | Needs to listen on TCP or UDP. |
|
||||
| `tcp_fast_open` | Needs to listen on TCP. |
|
||||
| `udp_timeout` | Needs to assemble UDP connections, currently Tun and Shadowsocks. |
|
||||
| `proxy_protocol` | Needs to listen on TCP. |
|
||||
|
||||
#### listen
|
||||
|
||||
==Required==
|
||||
|
||||
Listen address.
|
||||
|
||||
#### listen_port
|
||||
|
||||
Listen port.
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
Enable tcp fast open for listener.
|
||||
|
||||
#### sniff
|
||||
|
||||
Enable sniffing.
|
||||
|
||||
See [Protocol Sniff](/configuration/route/sniff/) for details.
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
Override the connection destination address with the sniffed domain.
|
||||
|
||||
If the domain name is invalid (like tor), this will not work.
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
|
||||
|
||||
If set, the requested domain name will be resolved to IP before routing.
|
||||
|
||||
If `sniff_override_destination` is in effect, its value will be taken as a fallback.
|
||||
|
||||
#### udp_timeout
|
||||
|
||||
UDP NAT expiration time in seconds, default is 300 (5 minutes).
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
Parse [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header.
|
||||
|
||||
#### detour
|
||||
|
||||
If set, connections will be forwarded to the specified inbound.
|
||||
|
||||
Requires target inbound support, see [Injectable](/configuration/inbound/#fields).
|
||||
@@ -1,72 +0,0 @@
|
||||
### 结构
|
||||
|
||||
```json
|
||||
{
|
||||
"listen": "::",
|
||||
"listen_port": 5353,
|
||||
"tcp_fast_open": false,
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"udp_timeout": 300,
|
||||
"detour": "another-in"
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 可用上下文 |
|
||||
|------------------|-------------------------------------|
|
||||
| `listen` | 需要监听 TCP 或 UDP。 |
|
||||
| `listen_port` | 需要监听 TCP 或 UDP。 |
|
||||
| `tcp_fast_open` | 需要监听 TCP。 |
|
||||
| `udp_timeout` | 需要组装 UDP 连接, 当前为 Tun 和 Shadowsocks。 |
|
||||
| `proxy_protocol` | 需要监听 TCP。 |
|
||||
|
||||
### 字段
|
||||
|
||||
#### listen
|
||||
|
||||
==必填==
|
||||
|
||||
监听地址。
|
||||
|
||||
#### listen_port
|
||||
|
||||
监听端口。
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
为监听器启用 TCP 快速打开。
|
||||
|
||||
#### sniff
|
||||
|
||||
启用协议探测。
|
||||
|
||||
参阅 [协议探测](/zh/configuration/route/sniff/)
|
||||
|
||||
#### sniff_override_destination
|
||||
|
||||
用探测出的域名覆盖连接目标地址。
|
||||
|
||||
如果域名无效(如 Tor),将不生效。
|
||||
|
||||
#### domain_strategy
|
||||
|
||||
可选值: `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
|
||||
|
||||
如果设置,请求的域名将在路由之前解析为 IP。
|
||||
|
||||
如果 `sniff_override_destination` 生效,它的值将作为后备。
|
||||
|
||||
#### udp_timeout
|
||||
|
||||
UDP NAT 过期时间,以秒为单位,默认为 300(5 分钟)。
|
||||
|
||||
#### proxy_protocol
|
||||
|
||||
解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。
|
||||
|
||||
#### detour
|
||||
|
||||
如果设置,连接将被转发到指定的入站。
|
||||
|
||||
需要目标入站支持,参阅 [注入支持](/zh/configuration/inbound/#_3)。
|
||||
@@ -1,55 +0,0 @@
|
||||
#### Server
|
||||
|
||||
```json
|
||||
{
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "shadowtls",
|
||||
"listen": "::",
|
||||
"listen_port": 4443,
|
||||
"handshake": {
|
||||
"server": "google.com",
|
||||
"server_port": 443
|
||||
},
|
||||
"detour": "shadowsocks-in"
|
||||
},
|
||||
{
|
||||
"type": "shadowsocks",
|
||||
"tag": "shadowsocks-in",
|
||||
"listen": "127.0.0.1",
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg=="
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Client
|
||||
|
||||
```json
|
||||
{
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "shadowsocks",
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"detour": "shadowtls-out",
|
||||
"multiplex": {
|
||||
"enabled": true,
|
||||
"max_connections": 4,
|
||||
"min_streams": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "shadowtls",
|
||||
"tag": "shadowtls-out",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 4443,
|
||||
"tls": {
|
||||
"enabled": true,
|
||||
"server_name": "google.com"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -11,7 +11,7 @@ the public internet.
|
||||
|
||||
##### on Linux
|
||||
|
||||
`auto-route` cannot automatically hijack DNS requests with `systemd-resolved` enabled, you can switch to NetworkManager.
|
||||
`auto-route` cannot automatically hijack DNS requests with `systemd-resoled` enabled, you can switch to NetworkManager.
|
||||
|
||||
#### System proxy
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
##### Linux
|
||||
|
||||
`auto-route` 无法自动劫持 DNS 请求如果 `systemd-resolved` 开启, 您可以切换到 NetworkManager.
|
||||
`auto-route` 无法自动劫持 DNS 请求如果 `systemd-resoled` 开启, 您可以切换到 NetworkManager.
|
||||
|
||||
#### 系统代理
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ func getConfigs(logFactory log.Factory) func(w http.ResponseWriter, r *http.Requ
|
||||
logLevel := logFactory.Level()
|
||||
if logLevel == log.LevelTrace {
|
||||
logLevel = log.LevelDebug
|
||||
} else if logLevel < log.LevelError {
|
||||
} else if logLevel > log.LevelError {
|
||||
logLevel = log.LevelError
|
||||
}
|
||||
render.JSON(w, r, &configSchema{
|
||||
|
||||
@@ -75,13 +75,11 @@ func proxyInfo(server *Server, detour adapter.Outbound) *badjson.JSONObject {
|
||||
clashType = "Shadowsocks"
|
||||
case C.TypeVMess:
|
||||
clashType = "Vmess"
|
||||
case C.TypeTrojan:
|
||||
clashType = "Trojan"
|
||||
case C.TypeSelector:
|
||||
clashType = "Selector"
|
||||
isGroup = true
|
||||
default:
|
||||
clashType = "Socks"
|
||||
clashType = "Unknown"
|
||||
}
|
||||
info.Put("type", clashType)
|
||||
info.Put("name", detour.Tag())
|
||||
|
||||
@@ -20,27 +20,25 @@ require (
|
||||
github.com/pires/go-proxyproto v0.6.2
|
||||
github.com/sagernet/certmagic v0.0.0-20220819042630-4a57f8b6853a
|
||||
github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb
|
||||
github.com/sagernet/sing v0.0.0-20220903085538-02b9ca1cc133
|
||||
github.com/sagernet/sing v0.0.0-20220826124916-d4ba8fdfac88
|
||||
github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666
|
||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6
|
||||
github.com/sagernet/sing-tun v0.0.0-20220828031750-185b6c880a83
|
||||
github.com/sagernet/sing-vmess v0.0.0-20220907073918-72d7fdf6825f
|
||||
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195
|
||||
github.com/sagernet/sing-vmess v0.0.0-20220827032426-01665c9c4e31
|
||||
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939
|
||||
github.com/spf13/cobra v1.5.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
go.uber.org/atomic v1.10.0
|
||||
go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
|
||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b
|
||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220829161405-d1d08426b27b
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478
|
||||
google.golang.org/grpc v1.49.0
|
||||
google.golang.org/protobuf v1.28.1
|
||||
gvisor.dev/gvisor v0.0.0-20220819163037-ba6e795b139a
|
||||
)
|
||||
|
||||
//replace github.com/sagernet/sing => ../sing
|
||||
|
||||
require (
|
||||
github.com/ajg/form v1.5.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
|
||||
@@ -135,18 +135,18 @@ github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb h1:wc0yQ+SBn4TaTY
|
||||
github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb/go.mod h1:MIccjRKnPTjWwAOpl+AUGWOkzyTd9tERytudxu+1ra4=
|
||||
github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
||||
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
||||
github.com/sagernet/sing v0.0.0-20220903085538-02b9ca1cc133 h1:krnb8wKEFIdXhmJYlhJMbEcPsJFISy2fz90uHVz7hMU=
|
||||
github.com/sagernet/sing v0.0.0-20220903085538-02b9ca1cc133/go.mod h1:kZvzh1VDa/Dg/Bt5WaYKU0jl5ept8KKDpl3Ay4gRtRQ=
|
||||
github.com/sagernet/sing v0.0.0-20220826124916-d4ba8fdfac88 h1:wxUQfVBqiUtAemytzP9mNjAkSiI0nVsRZBQvCLP8r5g=
|
||||
github.com/sagernet/sing v0.0.0-20220826124916-d4ba8fdfac88/go.mod h1:kZvzh1VDa/Dg/Bt5WaYKU0jl5ept8KKDpl3Ay4gRtRQ=
|
||||
github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666 h1:XUTocA/Ek0dFxUX+xJCWMPPFZCn2GC/uLrBjTSr1vHY=
|
||||
github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666/go.mod h1:eDyH7AJmqBGjZQdQmpZIzlbTREudZuWDExMuGKgjRVM=
|
||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4=
|
||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
|
||||
github.com/sagernet/sing-tun v0.0.0-20220828031750-185b6c880a83 h1:SoWiHYuOCVedqA7T/CJSZUUrcPGKQb2wFKEq8DphiAI=
|
||||
github.com/sagernet/sing-tun v0.0.0-20220828031750-185b6c880a83/go.mod h1:76r07HS1WRcEI4mE9pFsohfTBUt1j/G9Avz6DaOP3VU=
|
||||
github.com/sagernet/sing-vmess v0.0.0-20220907073918-72d7fdf6825f h1:6l9aXZqAl1JqXJWi89KHpWnM/moQUPGG+XiwMc+yD0A=
|
||||
github.com/sagernet/sing-vmess v0.0.0-20220907073918-72d7fdf6825f/go.mod h1:u66Vv7NHXJWfeAmhh7JuJp/cwxmuQlM56QoZ7B7Mmd0=
|
||||
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 h1:5VBIbVw9q7aKbrFdT83mjkyvQ+VaRsQ6yflTepfln38=
|
||||
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8=
|
||||
github.com/sagernet/sing-vmess v0.0.0-20220827032426-01665c9c4e31 h1:FAsJsVwpPcoITcj6/9JxRKxy8n3bIKLqKmDGVzmfeOo=
|
||||
github.com/sagernet/sing-vmess v0.0.0-20220827032426-01665c9c4e31/go.mod h1:82O6gzbxLha/W/jxSVQbsqf2lVdRTjMIgyLug0lpJps=
|
||||
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 h1:pB1Dh1NbwVrLhQhotr4O4Hs3yhiBzmg3AvnUyYjL4x4=
|
||||
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8=
|
||||
github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
|
||||
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
@@ -181,8 +181,8 @@ golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaE
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d h1:3qF+Z8Hkrw9sOhrFHti9TlB1Hkac1x+DNRkv0XQiFjo=
|
||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
|
||||
@@ -244,8 +244,8 @@ golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
|
||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 h1:UiNENfZ8gDvpiWw7IpOMQ27spWmThO1RwwdQVbJahJM=
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -276,8 +276,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY=
|
||||
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220829161405-d1d08426b27b h1:qgrKnOfe1zyURRNdmDlGbN32i38Zjmw0B1+TMdHcOvg=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220829161405-d1d08426b27b/go.mod h1:6y4CqPAy54NwiN4nC8K+R1eMpQDB1P2d25qmunh2RSA=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478 h1:vDy//hdR+GnROE3OdYbQKt9rdtNdHkDtONvpRwmls/0=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478/go.mod h1:bVQfyl2sCM/QIIGHpWbFGfHPuDvqnCNkT6MQLTCjO/U=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
|
||||
@@ -39,8 +39,6 @@ func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, o
|
||||
return NewNaive(ctx, router, logger, options.Tag, options.NaiveOptions)
|
||||
case C.TypeHysteria:
|
||||
return NewHysteria(ctx, router, logger, options.Tag, options.HysteriaOptions)
|
||||
case C.TypeShadowTLS:
|
||||
return NewShadowTLS(ctx, router, logger, options.Tag, options.ShadowTLSOptions)
|
||||
default:
|
||||
return nil, E.New("unknown inbound type: ", options.Type)
|
||||
}
|
||||
|
||||
+279
-5
@@ -3,18 +3,25 @@ package inbound
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/proxyproto"
|
||||
"github.com/sagernet/sing-box/common/settings"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing-dns"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
"github.com/database64128/tfo-go"
|
||||
)
|
||||
|
||||
var _ adapter.Inbound = (*myInboundAdapter)(nil)
|
||||
@@ -55,10 +62,6 @@ func (a *myInboundAdapter) Tag() string {
|
||||
return a.tag
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) Network() []string {
|
||||
return a.network
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) Start() error {
|
||||
var err error
|
||||
if common.Contains(a.network, N.NetworkTCP) {
|
||||
@@ -99,6 +102,38 @@ func (a *myInboundAdapter) Start() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) ListenTCP() (net.Listener, error) {
|
||||
var err error
|
||||
bindAddr := M.SocksaddrFrom(netip.Addr(a.listenOptions.Listen), a.listenOptions.ListenPort)
|
||||
var tcpListener net.Listener
|
||||
if !a.listenOptions.TCPFastOpen {
|
||||
tcpListener, err = net.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
|
||||
} else {
|
||||
tcpListener, err = tfo.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
|
||||
}
|
||||
if err == nil {
|
||||
a.logger.Info("tcp server started at ", tcpListener.Addr())
|
||||
}
|
||||
if a.listenOptions.ProxyProtocol {
|
||||
a.logger.Debug("proxy protocol enabled")
|
||||
tcpListener = &proxyproto.Listener{Listener: tcpListener}
|
||||
}
|
||||
a.tcpListener = tcpListener
|
||||
return tcpListener, err
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) ListenUDP() (net.PacketConn, error) {
|
||||
bindAddr := M.SocksaddrFrom(netip.Addr(a.listenOptions.Listen), a.listenOptions.ListenPort)
|
||||
udpConn, err := net.ListenUDP(M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.UDPAddr())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a.udpConn = udpConn
|
||||
a.udpAddr = bindAddr
|
||||
a.logger.Info("udp server started at ", udpConn.LocalAddr())
|
||||
return udpConn, err
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) Close() error {
|
||||
var err error
|
||||
if a.clearSystemProxy != nil {
|
||||
@@ -135,10 +170,20 @@ func (a *myInboundAdapter) newPacketConnection(ctx context.Context, conn N.Packe
|
||||
return a.router.RoutePacketConnection(ctx, conn, metadata)
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) loopTCPIn() {
|
||||
tcpListener := a.tcpListener
|
||||
for {
|
||||
conn, err := tcpListener.Accept()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
go a.injectTCP(conn)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) createMetadata(conn net.Conn, metadata adapter.InboundContext) adapter.InboundContext {
|
||||
metadata.Inbound = a.tag
|
||||
metadata.InboundType = a.protocol
|
||||
metadata.InboundDetour = a.listenOptions.Detour
|
||||
metadata.SniffEnabled = a.listenOptions.SniffEnabled
|
||||
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
|
||||
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
|
||||
@@ -154,6 +199,166 @@ func (a *myInboundAdapter) createMetadata(conn net.Conn, metadata adapter.Inboun
|
||||
return metadata
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) injectTCP(conn net.Conn) {
|
||||
ctx := log.ContextWithNewID(a.ctx)
|
||||
metadata := a.createMetadata(conn, adapter.InboundContext{})
|
||||
a.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
|
||||
hErr := a.connHandler.NewConnection(ctx, conn, metadata)
|
||||
if hErr != nil {
|
||||
conn.Close()
|
||||
a.NewError(ctx, E.Cause(hErr, "process connection from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) routeTCP(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) {
|
||||
a.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
|
||||
hErr := a.newConnection(ctx, conn, metadata)
|
||||
if hErr != nil {
|
||||
conn.Close()
|
||||
a.NewError(ctx, E.Cause(hErr, "process connection from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) loopUDPIn() {
|
||||
defer close(a.packetOutboundClosed)
|
||||
_buffer := buf.StackNewPacket()
|
||||
defer common.KeepAlive(_buffer)
|
||||
buffer := common.Dup(_buffer)
|
||||
defer buffer.Release()
|
||||
buffer.IncRef()
|
||||
defer buffer.DecRef()
|
||||
packetService := (*myInboundPacketAdapter)(a)
|
||||
for {
|
||||
buffer.Reset()
|
||||
n, addr, err := a.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
buffer.Truncate(n)
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = a.tag
|
||||
metadata.InboundType = a.protocol
|
||||
metadata.SniffEnabled = a.listenOptions.SniffEnabled
|
||||
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
|
||||
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
|
||||
metadata.Source = M.SocksaddrFromNetIP(addr)
|
||||
metadata.OriginDestination = a.udpAddr
|
||||
err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
|
||||
if err != nil {
|
||||
a.newError(E.Cause(err, "process packet from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) loopUDPOOBIn() {
|
||||
defer close(a.packetOutboundClosed)
|
||||
_buffer := buf.StackNewPacket()
|
||||
defer common.KeepAlive(_buffer)
|
||||
buffer := common.Dup(_buffer)
|
||||
defer buffer.Release()
|
||||
buffer.IncRef()
|
||||
defer buffer.DecRef()
|
||||
packetService := (*myInboundPacketAdapter)(a)
|
||||
oob := make([]byte, 1024)
|
||||
for {
|
||||
buffer.Reset()
|
||||
n, oobN, _, addr, err := a.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
buffer.Truncate(n)
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = a.tag
|
||||
metadata.InboundType = a.protocol
|
||||
metadata.SniffEnabled = a.listenOptions.SniffEnabled
|
||||
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
|
||||
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
|
||||
metadata.Source = M.SocksaddrFromNetIP(addr)
|
||||
metadata.OriginDestination = a.udpAddr
|
||||
err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata)
|
||||
if err != nil {
|
||||
a.newError(E.Cause(err, "process packet from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) loopUDPInThreadSafe() {
|
||||
defer close(a.packetOutboundClosed)
|
||||
packetService := (*myInboundPacketAdapter)(a)
|
||||
for {
|
||||
buffer := buf.NewPacket()
|
||||
n, addr, err := a.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
|
||||
if err != nil {
|
||||
buffer.Release()
|
||||
return
|
||||
}
|
||||
buffer.Truncate(n)
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = a.tag
|
||||
metadata.InboundType = a.protocol
|
||||
metadata.SniffEnabled = a.listenOptions.SniffEnabled
|
||||
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
|
||||
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
|
||||
metadata.Source = M.SocksaddrFromNetIP(addr)
|
||||
metadata.OriginDestination = a.udpAddr
|
||||
err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
|
||||
if err != nil {
|
||||
buffer.Release()
|
||||
a.newError(E.Cause(err, "process packet from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) loopUDPOOBInThreadSafe() {
|
||||
defer close(a.packetOutboundClosed)
|
||||
packetService := (*myInboundPacketAdapter)(a)
|
||||
oob := make([]byte, 1024)
|
||||
for {
|
||||
buffer := buf.NewPacket()
|
||||
n, oobN, _, addr, err := a.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob)
|
||||
if err != nil {
|
||||
buffer.Release()
|
||||
return
|
||||
}
|
||||
buffer.Truncate(n)
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = a.tag
|
||||
metadata.InboundType = a.protocol
|
||||
metadata.SniffEnabled = a.listenOptions.SniffEnabled
|
||||
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
|
||||
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
|
||||
metadata.Source = M.SocksaddrFromNetIP(addr)
|
||||
metadata.OriginDestination = a.udpAddr
|
||||
err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata)
|
||||
if err != nil {
|
||||
buffer.Release()
|
||||
a.newError(E.Cause(err, "process packet from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) loopUDPOut() {
|
||||
for {
|
||||
select {
|
||||
case packet := <-a.packetOutbound:
|
||||
err := a.writePacket(packet.buffer, packet.destination)
|
||||
if err != nil && !E.IsClosed(err) {
|
||||
a.newError(E.New("write back udp: ", err))
|
||||
}
|
||||
continue
|
||||
case <-a.packetOutboundClosed:
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case packet := <-a.packetOutbound:
|
||||
packet.buffer.Release()
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) newError(err error) {
|
||||
a.logger.Error(err)
|
||||
}
|
||||
@@ -170,3 +375,72 @@ func NewError(logger log.ContextLogger, ctx context.Context, err error) {
|
||||
}
|
||||
logger.ErrorContext(ctx, err)
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) writePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
|
||||
defer buffer.Release()
|
||||
if destination.IsFqdn() {
|
||||
udpAddr, err := net.ResolveUDPAddr(N.NetworkUDP, destination.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return common.Error(a.udpConn.WriteTo(buffer.Bytes(), udpAddr))
|
||||
}
|
||||
return common.Error(a.udpConn.WriteToUDPAddrPort(buffer.Bytes(), destination.AddrPort()))
|
||||
}
|
||||
|
||||
type myInboundPacketAdapter myInboundAdapter
|
||||
|
||||
func (s *myInboundPacketAdapter) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) {
|
||||
n, addr, err := s.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
|
||||
if err != nil {
|
||||
return M.Socksaddr{}, err
|
||||
}
|
||||
buffer.Truncate(n)
|
||||
return M.SocksaddrFromNetIP(addr), nil
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) WriteIsThreadUnsafe() {
|
||||
}
|
||||
|
||||
type myInboundPacket struct {
|
||||
buffer *buf.Buffer
|
||||
destination M.Socksaddr
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) Upstream() any {
|
||||
return s.udpConn
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
|
||||
s.packetAccess.RLock()
|
||||
defer s.packetAccess.RUnlock()
|
||||
|
||||
select {
|
||||
case <-s.packetOutboundClosed:
|
||||
return os.ErrClosed
|
||||
default:
|
||||
}
|
||||
|
||||
s.packetOutbound <- &myInboundPacket{buffer, destination}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) Close() error {
|
||||
return s.udpConn.Close()
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) LocalAddr() net.Addr {
|
||||
return s.udpConn.LocalAddr()
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) SetDeadline(t time.Time) error {
|
||||
return s.udpConn.SetDeadline(t)
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) SetReadDeadline(t time.Time) error {
|
||||
return s.udpConn.SetReadDeadline(t)
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) SetWriteDeadline(t time.Time) error {
|
||||
return s.udpConn.SetWriteDeadline(t)
|
||||
}
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
package inbound
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/proxyproto"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
"github.com/database64128/tfo-go"
|
||||
)
|
||||
|
||||
func (a *myInboundAdapter) ListenTCP() (net.Listener, error) {
|
||||
var err error
|
||||
bindAddr := M.SocksaddrFrom(netip.Addr(a.listenOptions.Listen), a.listenOptions.ListenPort)
|
||||
var tcpListener net.Listener
|
||||
if !a.listenOptions.TCPFastOpen {
|
||||
tcpListener, err = net.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
|
||||
} else {
|
||||
tcpListener, err = tfo.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
|
||||
}
|
||||
if err == nil {
|
||||
a.logger.Info("tcp server started at ", tcpListener.Addr())
|
||||
}
|
||||
if a.listenOptions.ProxyProtocol {
|
||||
a.logger.Debug("proxy protocol enabled")
|
||||
tcpListener = &proxyproto.Listener{Listener: tcpListener}
|
||||
}
|
||||
a.tcpListener = tcpListener
|
||||
return tcpListener, err
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) loopTCPIn() {
|
||||
tcpListener := a.tcpListener
|
||||
for {
|
||||
conn, err := tcpListener.Accept()
|
||||
if err != nil {
|
||||
if E.IsClosed(err) {
|
||||
return
|
||||
}
|
||||
a.logger.Error("accept: ", err)
|
||||
continue
|
||||
}
|
||||
go a.injectTCP(conn, adapter.InboundContext{})
|
||||
}
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) injectTCP(conn net.Conn, metadata adapter.InboundContext) {
|
||||
ctx := log.ContextWithNewID(a.ctx)
|
||||
metadata = a.createMetadata(conn, metadata)
|
||||
a.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
|
||||
hErr := a.connHandler.NewConnection(ctx, conn, metadata)
|
||||
if hErr != nil {
|
||||
conn.Close()
|
||||
a.NewError(ctx, E.Cause(hErr, "process connection from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) routeTCP(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) {
|
||||
a.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
|
||||
hErr := a.newConnection(ctx, conn, metadata)
|
||||
if hErr != nil {
|
||||
conn.Close()
|
||||
a.NewError(ctx, E.Cause(hErr, "process connection from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
@@ -1,237 +0,0 @@
|
||||
package inbound
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-dns"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
func (a *myInboundAdapter) ListenUDP() (net.PacketConn, error) {
|
||||
bindAddr := M.SocksaddrFrom(netip.Addr(a.listenOptions.Listen), a.listenOptions.ListenPort)
|
||||
udpConn, err := net.ListenUDP(M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.UDPAddr())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a.udpConn = udpConn
|
||||
a.udpAddr = bindAddr
|
||||
a.logger.Info("udp server started at ", udpConn.LocalAddr())
|
||||
return udpConn, err
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) loopUDPIn() {
|
||||
defer close(a.packetOutboundClosed)
|
||||
_buffer := buf.StackNewPacket()
|
||||
defer common.KeepAlive(_buffer)
|
||||
buffer := common.Dup(_buffer)
|
||||
defer buffer.Release()
|
||||
buffer.IncRef()
|
||||
defer buffer.DecRef()
|
||||
packetService := (*myInboundPacketAdapter)(a)
|
||||
for {
|
||||
buffer.Reset()
|
||||
n, addr, err := a.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
buffer.Truncate(n)
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = a.tag
|
||||
metadata.InboundType = a.protocol
|
||||
metadata.SniffEnabled = a.listenOptions.SniffEnabled
|
||||
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
|
||||
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
|
||||
metadata.Source = M.SocksaddrFromNetIP(addr)
|
||||
metadata.OriginDestination = a.udpAddr
|
||||
err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
|
||||
if err != nil {
|
||||
a.newError(E.Cause(err, "process packet from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) loopUDPOOBIn() {
|
||||
defer close(a.packetOutboundClosed)
|
||||
_buffer := buf.StackNewPacket()
|
||||
defer common.KeepAlive(_buffer)
|
||||
buffer := common.Dup(_buffer)
|
||||
defer buffer.Release()
|
||||
buffer.IncRef()
|
||||
defer buffer.DecRef()
|
||||
packetService := (*myInboundPacketAdapter)(a)
|
||||
oob := make([]byte, 1024)
|
||||
for {
|
||||
buffer.Reset()
|
||||
n, oobN, _, addr, err := a.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
buffer.Truncate(n)
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = a.tag
|
||||
metadata.InboundType = a.protocol
|
||||
metadata.SniffEnabled = a.listenOptions.SniffEnabled
|
||||
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
|
||||
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
|
||||
metadata.Source = M.SocksaddrFromNetIP(addr)
|
||||
metadata.OriginDestination = a.udpAddr
|
||||
err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata)
|
||||
if err != nil {
|
||||
a.newError(E.Cause(err, "process packet from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) loopUDPInThreadSafe() {
|
||||
defer close(a.packetOutboundClosed)
|
||||
packetService := (*myInboundPacketAdapter)(a)
|
||||
for {
|
||||
buffer := buf.NewPacket()
|
||||
n, addr, err := a.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
|
||||
if err != nil {
|
||||
buffer.Release()
|
||||
return
|
||||
}
|
||||
buffer.Truncate(n)
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = a.tag
|
||||
metadata.InboundType = a.protocol
|
||||
metadata.SniffEnabled = a.listenOptions.SniffEnabled
|
||||
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
|
||||
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
|
||||
metadata.Source = M.SocksaddrFromNetIP(addr)
|
||||
metadata.OriginDestination = a.udpAddr
|
||||
err = a.packetHandler.NewPacket(a.ctx, packetService, buffer, metadata)
|
||||
if err != nil {
|
||||
buffer.Release()
|
||||
a.newError(E.Cause(err, "process packet from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) loopUDPOOBInThreadSafe() {
|
||||
defer close(a.packetOutboundClosed)
|
||||
packetService := (*myInboundPacketAdapter)(a)
|
||||
oob := make([]byte, 1024)
|
||||
for {
|
||||
buffer := buf.NewPacket()
|
||||
n, oobN, _, addr, err := a.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob)
|
||||
if err != nil {
|
||||
buffer.Release()
|
||||
return
|
||||
}
|
||||
buffer.Truncate(n)
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = a.tag
|
||||
metadata.InboundType = a.protocol
|
||||
metadata.SniffEnabled = a.listenOptions.SniffEnabled
|
||||
metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination
|
||||
metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy)
|
||||
metadata.Source = M.SocksaddrFromNetIP(addr)
|
||||
metadata.OriginDestination = a.udpAddr
|
||||
err = a.oobPacketHandler.NewPacket(a.ctx, packetService, buffer, oob[:oobN], metadata)
|
||||
if err != nil {
|
||||
buffer.Release()
|
||||
a.newError(E.Cause(err, "process packet from ", metadata.Source))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) loopUDPOut() {
|
||||
for {
|
||||
select {
|
||||
case packet := <-a.packetOutbound:
|
||||
err := a.writePacket(packet.buffer, packet.destination)
|
||||
if err != nil && !E.IsClosed(err) {
|
||||
a.newError(E.New("write back udp: ", err))
|
||||
}
|
||||
continue
|
||||
case <-a.packetOutboundClosed:
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case packet := <-a.packetOutbound:
|
||||
packet.buffer.Release()
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) writePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
|
||||
defer buffer.Release()
|
||||
if destination.IsFqdn() {
|
||||
udpAddr, err := net.ResolveUDPAddr(N.NetworkUDP, destination.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return common.Error(a.udpConn.WriteTo(buffer.Bytes(), udpAddr))
|
||||
}
|
||||
return common.Error(a.udpConn.WriteToUDPAddrPort(buffer.Bytes(), destination.AddrPort()))
|
||||
}
|
||||
|
||||
type myInboundPacketAdapter myInboundAdapter
|
||||
|
||||
func (s *myInboundPacketAdapter) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) {
|
||||
n, addr, err := s.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
|
||||
if err != nil {
|
||||
return M.Socksaddr{}, err
|
||||
}
|
||||
buffer.Truncate(n)
|
||||
return M.SocksaddrFromNetIP(addr), nil
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) WriteIsThreadUnsafe() {
|
||||
}
|
||||
|
||||
type myInboundPacket struct {
|
||||
buffer *buf.Buffer
|
||||
destination M.Socksaddr
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) Upstream() any {
|
||||
return s.udpConn
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
|
||||
s.packetAccess.RLock()
|
||||
defer s.packetAccess.RUnlock()
|
||||
|
||||
select {
|
||||
case <-s.packetOutboundClosed:
|
||||
return os.ErrClosed
|
||||
default:
|
||||
}
|
||||
|
||||
s.packetOutbound <- &myInboundPacket{buffer, destination}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) Close() error {
|
||||
return s.udpConn.Close()
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) LocalAddr() net.Addr {
|
||||
return s.udpConn.LocalAddr()
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) SetDeadline(t time.Time) error {
|
||||
return s.udpConn.SetDeadline(t)
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) SetReadDeadline(t time.Time) error {
|
||||
return s.udpConn.SetReadDeadline(t)
|
||||
}
|
||||
|
||||
func (s *myInboundPacketAdapter) SetWriteDeadline(t time.Time) error {
|
||||
return s.udpConn.SetWriteDeadline(t)
|
||||
}
|
||||
+1
-9
@@ -5,7 +5,6 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
@@ -18,10 +17,7 @@ import (
|
||||
"github.com/sagernet/sing/protocol/http"
|
||||
)
|
||||
|
||||
var (
|
||||
_ adapter.Inbound = (*HTTP)(nil)
|
||||
_ adapter.InjectableInbound = (*HTTP)(nil)
|
||||
)
|
||||
var _ adapter.Inbound = (*HTTP)(nil)
|
||||
|
||||
type HTTP struct {
|
||||
myInboundAdapter
|
||||
@@ -78,10 +74,6 @@ func (h *HTTP) NewConnection(ctx context.Context, conn net.Conn, metadata adapte
|
||||
return http.HandleConnection(ctx, conn, std_bufio.NewReader(conn), h.authenticator, h.upstreamUserHandler(metadata), adapter.UpstreamMetadata(metadata))
|
||||
}
|
||||
|
||||
func (h *HTTP) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
|
||||
func (a *myInboundAdapter) upstreamUserHandler(metadata adapter.InboundContext) adapter.UpstreamHandlerAdapter {
|
||||
return adapter.NewUpstreamHandler(metadata, a.newUserConnection, a.streamUserPacketConnection, a)
|
||||
}
|
||||
|
||||
+1
-9
@@ -4,7 +4,6 @@ import (
|
||||
std_bufio "bufio"
|
||||
"context"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
@@ -21,10 +20,7 @@ import (
|
||||
"github.com/sagernet/sing/protocol/socks/socks5"
|
||||
)
|
||||
|
||||
var (
|
||||
_ adapter.Inbound = (*Mixed)(nil)
|
||||
_ adapter.InjectableInbound = (*Mixed)(nil)
|
||||
)
|
||||
var _ adapter.Inbound = (*Mixed)(nil)
|
||||
|
||||
type Mixed struct {
|
||||
myInboundAdapter
|
||||
@@ -61,7 +57,3 @@ func (h *Mixed) NewConnection(ctx context.Context, conn net.Conn, metadata adapt
|
||||
reader := std_bufio.NewReader(bufio.NewCachedReader(conn, buf.As([]byte{headerType})))
|
||||
return http.HandleConnection(ctx, conn, reader, h.authenticator, h.upstreamUserHandler(metadata), adapter.UpstreamMetadata(metadata))
|
||||
}
|
||||
|
||||
func (h *Mixed) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user