mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-08-29 05:27:35 +08:00
Compare commits
108 Commits
79bd6c53b1
...
35df5635c5
Author | SHA1 | Date | |
---|---|---|---|
![]() |
35df5635c5 | ||
![]() |
8f4bbf9a7a | ||
![]() |
9e3b34ea50 | ||
![]() |
983421c1cb | ||
![]() |
4861ceb6ee | ||
![]() |
4f4e3eb8c3 | ||
![]() |
7b7feb794e | ||
![]() |
b3b8d1fa29 | ||
![]() |
da924b51c8 | ||
![]() |
fb3983ff6d | ||
![]() |
07ec062876 | ||
![]() |
80f43fa51b | ||
![]() |
e0e9160290 | ||
![]() |
5d1f13385b | ||
![]() |
9ef08196a4 | ||
![]() |
cf26a7b6f6 | ||
![]() |
49efb2b8de | ||
![]() |
965bec8967 | ||
![]() |
cc34e8391d | ||
![]() |
b89158efb9 | ||
![]() |
a226bdca28 | ||
![]() |
360130af7b | ||
![]() |
f327ea7737 | ||
![]() |
90d6de9220 | ||
![]() |
6d71e440e0 | ||
![]() |
d249150a63 | ||
![]() |
b3921910e4 | ||
![]() |
b9163feb77 | ||
![]() |
40d7e13103 | ||
![]() |
7b56fb370f | ||
![]() |
6036174a37 | ||
![]() |
6ed4a3e25e | ||
![]() |
168809cfe2 | ||
![]() |
b6ca331c7d | ||
![]() |
d2a04c4e41 | ||
![]() |
027ff49390 | ||
![]() |
8936f41e54 | ||
![]() |
e8a6ae0ac7 | ||
![]() |
df36013d7d | ||
![]() |
a9cd830a9a | ||
![]() |
306abab55d | ||
![]() |
f7a92111c5 | ||
![]() |
dfe82895ab | ||
![]() |
973ab97813 | ||
![]() |
a78f3cb116 | ||
![]() |
13037a56d8 | ||
![]() |
3dc3a0b6e3 | ||
![]() |
577c51a1f1 | ||
![]() |
64db52f638 | ||
![]() |
1b6521f5f8 | ||
![]() |
ec8821fc94 | ||
![]() |
c90e0ad48d | ||
![]() |
38676a2f06 | ||
![]() |
8d2b641f92 | ||
![]() |
f0bf1f0ae8 | ||
![]() |
084071e882 | ||
![]() |
90499e90de | ||
![]() |
20055a362c | ||
![]() |
376dd20254 | ||
![]() |
9a83c088b1 | ||
![]() |
2b4c6f4ebb | ||
![]() |
3ca6fee62f | ||
![]() |
372ac544c8 | ||
![]() |
138c1e4969 | ||
![]() |
8a586db5f1 | ||
![]() |
9959239b1a | ||
![]() |
4d96d78cd8 | ||
![]() |
d3d58b37e8 | ||
![]() |
21e7bbdffc | ||
![]() |
c0b6a876ff | ||
![]() |
9b42c2efac | ||
![]() |
dc433869cd | ||
![]() |
98db9aa3ec | ||
![]() |
46a7a2b457 | ||
![]() |
279fa7379c | ||
![]() |
d896cbe623 | ||
![]() |
2b1d40c9b7 | ||
![]() |
ca304a9d6f | ||
![]() |
7bc733b5b1 | ||
![]() |
a6a934a91b | ||
![]() |
cf5a34a318 | ||
![]() |
9570568caa | ||
![]() |
bf1962cfe4 | ||
![]() |
e6a07492d0 | ||
![]() |
36b12f4ab5 | ||
![]() |
bc0cbef785 | ||
![]() |
8dc7698c5f | ||
![]() |
cc59cb27e9 | ||
![]() |
0e1c8a1134 | ||
![]() |
418f6fff49 | ||
![]() |
e5f87fab4b | ||
![]() |
61e9a9f674 | ||
![]() |
19fd3e836e | ||
![]() |
78515fd9c7 | ||
![]() |
7506b2711c | ||
![]() |
07817df680 | ||
![]() |
dc9b7c880d | ||
![]() |
b79f1b2540 | ||
![]() |
7487fa28be | ||
![]() |
10c7c67e3c | ||
![]() |
ca2a10f9f6 | ||
![]() |
ddc6cdc3fb | ||
![]() |
2e96569fef | ||
![]() |
fe5ee7d31d | ||
![]() |
06c2824df9 | ||
![]() |
b28d19cfa7 | ||
![]() |
1709ad7f7f | ||
![]() |
842f209da0 |
10
.github/workflows/build.yml
vendored
10
.github/workflows/build.yml
vendored
@ -46,7 +46,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ^1.24.4
|
go-version: ^1.24
|
||||||
- name: Check input version
|
- name: Check input version
|
||||||
if: github.event_name == 'workflow_dispatch'
|
if: github.event_name == 'workflow_dispatch'
|
||||||
run: |-
|
run: |-
|
||||||
@ -109,7 +109,7 @@ jobs:
|
|||||||
if: ${{ ! matrix.legacy_go }}
|
if: ${{ ! matrix.legacy_go }}
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ^1.24.4
|
go-version: ^1.24
|
||||||
- name: Cache Legacy Go
|
- name: Cache Legacy Go
|
||||||
if: matrix.require_legacy_go
|
if: matrix.require_legacy_go
|
||||||
id: cache-legacy-go
|
id: cache-legacy-go
|
||||||
@ -294,7 +294,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ^1.24.4
|
go-version: ^1.24
|
||||||
- name: Setup Android NDK
|
- name: Setup Android NDK
|
||||||
id: setup-ndk
|
id: setup-ndk
|
||||||
uses: nttld/setup-ndk@v1
|
uses: nttld/setup-ndk@v1
|
||||||
@ -374,7 +374,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ^1.24.4
|
go-version: ^1.24
|
||||||
- name: Setup Android NDK
|
- name: Setup Android NDK
|
||||||
id: setup-ndk
|
id: setup-ndk
|
||||||
uses: nttld/setup-ndk@v1
|
uses: nttld/setup-ndk@v1
|
||||||
@ -472,7 +472,7 @@ jobs:
|
|||||||
if: matrix.if
|
if: matrix.if
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ^1.24.4
|
go-version: ^1.24
|
||||||
- name: Setup Xcode stable
|
- name: Setup Xcode stable
|
||||||
if: matrix.if && github.ref == 'refs/heads/main-next'
|
if: matrix.if && github.ref == 'refs/heads/main-next'
|
||||||
run: |-
|
run: |-
|
||||||
|
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@ -28,7 +28,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ^1.24.4
|
go-version: ^1.24
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v8
|
uses: golangci/golangci-lint-action@v8
|
||||||
with:
|
with:
|
||||||
|
4
.github/workflows/linux.yml
vendored
4
.github/workflows/linux.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ^1.24.4
|
go-version: ^1.24
|
||||||
- name: Check input version
|
- name: Check input version
|
||||||
if: github.event_name == 'workflow_dispatch'
|
if: github.event_name == 'workflow_dispatch'
|
||||||
run: |-
|
run: |-
|
||||||
@ -66,7 +66,7 @@ jobs:
|
|||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ^1.24.4
|
go-version: ^1.24
|
||||||
- name: Setup Android NDK
|
- name: Setup Android NDK
|
||||||
if: matrix.os == 'android'
|
if: matrix.os == 'android'
|
||||||
uses: nttld/setup-ndk@v1
|
uses: nttld/setup-ndk@v1
|
||||||
|
@ -40,12 +40,7 @@ parseLine:
|
|||||||
if ruleLine == "" {
|
if ruleLine == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if strings.Contains(ruleLine, "!") {
|
if strings.HasPrefix(ruleLine, "!") || strings.HasPrefix(ruleLine, "#") {
|
||||||
continue
|
|
||||||
}
|
|
||||||
if strings.Contains(ruleLine, "#") {
|
|
||||||
ignoredLines++
|
|
||||||
logger.Debug("ignored unsupported cosmetic filter: ", ruleLine)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
originRuleLine := ruleLine
|
originRuleLine := ruleLine
|
||||||
@ -147,12 +142,9 @@ parseLine:
|
|||||||
logger.Debug("ignored unsupported rule with query: ", ruleLine)
|
logger.Debug("ignored unsupported rule with query: ", ruleLine)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if strings.Contains(ruleLine, "[") || strings.Contains(ruleLine, "]") {
|
if strings.Contains(ruleLine, "[") || strings.Contains(ruleLine, "]") ||
|
||||||
ignoredLines++
|
strings.Contains(ruleLine, "(") || strings.Contains(ruleLine, ")") ||
|
||||||
logger.Debug("ignored unsupported cosmetic filter: ", ruleLine)
|
strings.Contains(ruleLine, "!") || strings.Contains(ruleLine, "#") {
|
||||||
continue
|
|
||||||
}
|
|
||||||
if strings.Contains(ruleLine, "(") || strings.Contains(ruleLine, ")") {
|
|
||||||
ignoredLines++
|
ignoredLines++
|
||||||
logger.Debug("ignored unsupported cosmetic filter: ", ruleLine)
|
logger.Debug("ignored unsupported cosmetic filter: ", ruleLine)
|
||||||
continue
|
continue
|
||||||
@ -302,7 +294,9 @@ parseLine:
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.Info("parsed rules: ", len(ruleLines), "/", len(ruleLines)+ignoredLines)
|
if ignoredLines > 0 {
|
||||||
|
logger.Info("parsed rules: ", len(ruleLines), "/", len(ruleLines)+ignoredLines)
|
||||||
|
}
|
||||||
return []option.HeadlessRule{currentRule}, nil
|
return []option.HeadlessRule{currentRule}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
go.mod
2
go.mod
@ -34,7 +34,7 @@ require (
|
|||||||
github.com/sagernet/sing-shadowsocks v0.2.8
|
github.com/sagernet/sing-shadowsocks v0.2.8
|
||||||
github.com/sagernet/sing-shadowsocks2 v0.2.1
|
github.com/sagernet/sing-shadowsocks2 v0.2.1
|
||||||
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11
|
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11
|
||||||
github.com/sagernet/sing-tun v0.6.9-0.20250617062442-df4458520f26
|
github.com/sagernet/sing-tun v0.6.10-0.20250620051458-5e343c4b66b2
|
||||||
github.com/sagernet/sing-vmess v0.2.4-0.20250605032146-38cc72672c88
|
github.com/sagernet/sing-vmess v0.2.4-0.20250605032146-38cc72672c88
|
||||||
github.com/sagernet/smux v1.5.34-mod.2
|
github.com/sagernet/smux v1.5.34-mod.2
|
||||||
github.com/sagernet/tailscale v1.80.3-mod.5
|
github.com/sagernet/tailscale v1.80.3-mod.5
|
||||||
|
4
go.sum
4
go.sum
@ -180,8 +180,8 @@ github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnq
|
|||||||
github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
|
github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
|
||||||
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75l64tm9WvEFrYRE1t0YxoFdWQqw/h7Uhzj0vJ+w=
|
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75l64tm9WvEFrYRE1t0YxoFdWQqw/h7Uhzj0vJ+w=
|
||||||
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA=
|
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA=
|
||||||
github.com/sagernet/sing-tun v0.6.9-0.20250617062442-df4458520f26 h1:N9yAoqtQlawlJzLONjdQvIO3GJLEg9tZBfyKToSi0cM=
|
github.com/sagernet/sing-tun v0.6.10-0.20250620051458-5e343c4b66b2 h1:ykbqGFHDNVvp0jhgLime/XBAtQpcOcFpT8Rs5Hcc5n4=
|
||||||
github.com/sagernet/sing-tun v0.6.9-0.20250617062442-df4458520f26/go.mod h1:fisFCbC4Vfb6HqQNcwPJi2CDK2bf0Xapyz3j3t4cnHE=
|
github.com/sagernet/sing-tun v0.6.10-0.20250620051458-5e343c4b66b2/go.mod h1:fisFCbC4Vfb6HqQNcwPJi2CDK2bf0Xapyz3j3t4cnHE=
|
||||||
github.com/sagernet/sing-vmess v0.2.4-0.20250605032146-38cc72672c88 h1:0pVm8sPOel+BoiCddW3pV3cKDKEaSioVTYDdTSKjyFI=
|
github.com/sagernet/sing-vmess v0.2.4-0.20250605032146-38cc72672c88 h1:0pVm8sPOel+BoiCddW3pV3cKDKEaSioVTYDdTSKjyFI=
|
||||||
github.com/sagernet/sing-vmess v0.2.4-0.20250605032146-38cc72672c88/go.mod h1:IL8Rr+EGwuqijszZkNrEFTQDKhilEpkqFqOlvdpS6/w=
|
github.com/sagernet/sing-vmess v0.2.4-0.20250605032146-38cc72672c88/go.mod h1:IL8Rr+EGwuqijszZkNrEFTQDKhilEpkqFqOlvdpS6/w=
|
||||||
github.com/sagernet/smux v1.5.34-mod.2 h1:gkmBjIjlJ2zQKpLigOkFur5kBKdV6bNRoFu2WkltRQ4=
|
github.com/sagernet/smux v1.5.34-mod.2 h1:gkmBjIjlJ2zQKpLigOkFur5kBKdV6bNRoFu2WkltRQ4=
|
||||||
|
@ -2,7 +2,6 @@ package route
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -10,7 +9,7 @@ import (
|
|||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/dns"
|
"github.com/sagernet/sing-box/dns"
|
||||||
dnsOutbound "github.com/sagernet/sing-box/protocol/dns"
|
dnsOutbound "github.com/sagernet/sing-box/protocol/dns"
|
||||||
"github.com/sagernet/sing-tun"
|
R "github.com/sagernet/sing-box/route/rule"
|
||||||
"github.com/sagernet/sing/common/buf"
|
"github.com/sagernet/sing/common/buf"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
"github.com/sagernet/sing/common/logger"
|
"github.com/sagernet/sing/common/logger"
|
||||||
@ -65,7 +64,7 @@ func (r *Router) hijackDNSPacket(ctx context.Context, conn N.PacketConn, packetB
|
|||||||
|
|
||||||
func ExchangeDNSPacket(ctx context.Context, router adapter.DNSRouter, logger logger.ContextLogger, conn N.PacketConn, buffer *buf.Buffer, metadata adapter.InboundContext, destination M.Socksaddr) {
|
func ExchangeDNSPacket(ctx context.Context, router adapter.DNSRouter, logger logger.ContextLogger, conn N.PacketConn, buffer *buf.Buffer, metadata adapter.InboundContext, destination M.Socksaddr) {
|
||||||
err := exchangeDNSPacket(ctx, router, conn, buffer, metadata, destination)
|
err := exchangeDNSPacket(ctx, router, conn, buffer, metadata, destination)
|
||||||
if err != nil && !errors.Is(err, tun.ErrDrop) && !E.IsClosedOrCanceled(err) {
|
if err != nil && !R.IsRejected(err) && !E.IsClosedOrCanceled(err) {
|
||||||
logger.ErrorContext(ctx, E.Cause(err, "process DNS packet"))
|
logger.ErrorContext(ctx, E.Cause(err, "process DNS packet"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
"github.com/sagernet/sing-box/common/sniff"
|
"github.com/sagernet/sing-box/common/sniff"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/option"
|
"github.com/sagernet/sing-box/option"
|
||||||
"github.com/sagernet/sing-box/route/rule"
|
R "github.com/sagernet/sing-box/route/rule"
|
||||||
"github.com/sagernet/sing-mux"
|
"github.com/sagernet/sing-mux"
|
||||||
"github.com/sagernet/sing-vmess"
|
"github.com/sagernet/sing-vmess"
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
@ -49,7 +49,7 @@ func (r *Router) RouteConnectionEx(ctx context.Context, conn net.Conn, metadata
|
|||||||
err := r.routeConnection(ctx, conn, metadata, onClose)
|
err := r.routeConnection(ctx, conn, metadata, onClose)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
N.CloseOnHandshakeFailure(conn, onClose, err)
|
N.CloseOnHandshakeFailure(conn, onClose, err)
|
||||||
if E.IsClosedOrCanceled(err) {
|
if E.IsClosedOrCanceled(err) || R.IsRejected(err) {
|
||||||
r.logger.DebugContext(ctx, "connection closed: ", err)
|
r.logger.DebugContext(ctx, "connection closed: ", err)
|
||||||
} else {
|
} else {
|
||||||
r.logger.ErrorContext(ctx, err)
|
r.logger.ErrorContext(ctx, err)
|
||||||
@ -99,7 +99,7 @@ func (r *Router) routeConnection(ctx context.Context, conn net.Conn, metadata ad
|
|||||||
var selectedOutbound adapter.Outbound
|
var selectedOutbound adapter.Outbound
|
||||||
if selectedRule != nil {
|
if selectedRule != nil {
|
||||||
switch action := selectedRule.Action().(type) {
|
switch action := selectedRule.Action().(type) {
|
||||||
case *rule.RuleActionRoute:
|
case *R.RuleActionRoute:
|
||||||
var loaded bool
|
var loaded bool
|
||||||
selectedOutbound, loaded = r.outbound.Outbound(action.Outbound)
|
selectedOutbound, loaded = r.outbound.Outbound(action.Outbound)
|
||||||
if !loaded {
|
if !loaded {
|
||||||
@ -110,10 +110,10 @@ func (r *Router) routeConnection(ctx context.Context, conn net.Conn, metadata ad
|
|||||||
buf.ReleaseMulti(buffers)
|
buf.ReleaseMulti(buffers)
|
||||||
return E.New("TCP is not supported by outbound: ", selectedOutbound.Tag())
|
return E.New("TCP is not supported by outbound: ", selectedOutbound.Tag())
|
||||||
}
|
}
|
||||||
case *rule.RuleActionReject:
|
case *R.RuleActionReject:
|
||||||
buf.ReleaseMulti(buffers)
|
buf.ReleaseMulti(buffers)
|
||||||
return action.Error(ctx)
|
return action.Error(ctx)
|
||||||
case *rule.RuleActionHijackDNS:
|
case *R.RuleActionHijackDNS:
|
||||||
for _, buffer := range buffers {
|
for _, buffer := range buffers {
|
||||||
conn = bufio.NewCachedConn(conn, buffer)
|
conn = bufio.NewCachedConn(conn, buffer)
|
||||||
}
|
}
|
||||||
@ -151,7 +151,7 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
|
|||||||
}))
|
}))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
if E.IsClosedOrCanceled(err) {
|
if E.IsClosedOrCanceled(err) || R.IsRejected(err) {
|
||||||
r.logger.DebugContext(ctx, "connection closed: ", err)
|
r.logger.DebugContext(ctx, "connection closed: ", err)
|
||||||
} else {
|
} else {
|
||||||
r.logger.ErrorContext(ctx, err)
|
r.logger.ErrorContext(ctx, err)
|
||||||
@ -168,7 +168,7 @@ func (r *Router) RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn,
|
|||||||
err := r.routePacketConnection(ctx, conn, metadata, onClose)
|
err := r.routePacketConnection(ctx, conn, metadata, onClose)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
N.CloseOnHandshakeFailure(conn, onClose, err)
|
N.CloseOnHandshakeFailure(conn, onClose, err)
|
||||||
if E.IsClosedOrCanceled(err) {
|
if E.IsClosedOrCanceled(err) || R.IsRejected(err) {
|
||||||
r.logger.DebugContext(ctx, "connection closed: ", err)
|
r.logger.DebugContext(ctx, "connection closed: ", err)
|
||||||
} else {
|
} else {
|
||||||
r.logger.ErrorContext(ctx, err)
|
r.logger.ErrorContext(ctx, err)
|
||||||
@ -214,7 +214,7 @@ func (r *Router) routePacketConnection(ctx context.Context, conn N.PacketConn, m
|
|||||||
var selectReturn bool
|
var selectReturn bool
|
||||||
if selectedRule != nil {
|
if selectedRule != nil {
|
||||||
switch action := selectedRule.Action().(type) {
|
switch action := selectedRule.Action().(type) {
|
||||||
case *rule.RuleActionRoute:
|
case *R.RuleActionRoute:
|
||||||
var loaded bool
|
var loaded bool
|
||||||
selectedOutbound, loaded = r.outbound.Outbound(action.Outbound)
|
selectedOutbound, loaded = r.outbound.Outbound(action.Outbound)
|
||||||
if !loaded {
|
if !loaded {
|
||||||
@ -225,10 +225,10 @@ func (r *Router) routePacketConnection(ctx context.Context, conn N.PacketConn, m
|
|||||||
N.ReleaseMultiPacketBuffer(packetBuffers)
|
N.ReleaseMultiPacketBuffer(packetBuffers)
|
||||||
return E.New("UDP is not supported by outbound: ", selectedOutbound.Tag())
|
return E.New("UDP is not supported by outbound: ", selectedOutbound.Tag())
|
||||||
}
|
}
|
||||||
case *rule.RuleActionReject:
|
case *R.RuleActionReject:
|
||||||
N.ReleaseMultiPacketBuffer(packetBuffers)
|
N.ReleaseMultiPacketBuffer(packetBuffers)
|
||||||
return action.Error(ctx)
|
return action.Error(ctx)
|
||||||
case *rule.RuleActionHijackDNS:
|
case *R.RuleActionHijackDNS:
|
||||||
return r.hijackDNSPacket(ctx, conn, packetBuffers, metadata, onClose)
|
return r.hijackDNSPacket(ctx, conn, packetBuffers, metadata, onClose)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -266,7 +266,7 @@ func (r *Router) PreMatch(metadata adapter.InboundContext) error {
|
|||||||
if selectedRule == nil {
|
if selectedRule == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
rejectAction, isReject := selectedRule.Action().(*rule.RuleActionReject)
|
rejectAction, isReject := selectedRule.Action().(*R.RuleActionReject)
|
||||||
if !isReject {
|
if !isReject {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -342,7 +342,7 @@ func (r *Router) matchRule(
|
|||||||
//nolint:staticcheck
|
//nolint:staticcheck
|
||||||
if metadata.InboundOptions != common.DefaultValue[option.InboundOptions]() {
|
if metadata.InboundOptions != common.DefaultValue[option.InboundOptions]() {
|
||||||
if !preMatch && metadata.InboundOptions.SniffEnabled {
|
if !preMatch && metadata.InboundOptions.SniffEnabled {
|
||||||
newBuffer, newPackerBuffers, newErr := r.actionSniff(ctx, metadata, &rule.RuleActionSniff{
|
newBuffer, newPackerBuffers, newErr := r.actionSniff(ctx, metadata, &R.RuleActionSniff{
|
||||||
OverrideDestination: metadata.InboundOptions.SniffOverrideDestination,
|
OverrideDestination: metadata.InboundOptions.SniffOverrideDestination,
|
||||||
Timeout: time.Duration(metadata.InboundOptions.SniffTimeout),
|
Timeout: time.Duration(metadata.InboundOptions.SniffTimeout),
|
||||||
}, inputConn, inputPacketConn, nil)
|
}, inputConn, inputPacketConn, nil)
|
||||||
@ -357,7 +357,7 @@ func (r *Router) matchRule(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if C.DomainStrategy(metadata.InboundOptions.DomainStrategy) != C.DomainStrategyAsIS {
|
if C.DomainStrategy(metadata.InboundOptions.DomainStrategy) != C.DomainStrategyAsIS {
|
||||||
fatalErr = r.actionResolve(ctx, metadata, &rule.RuleActionResolve{
|
fatalErr = r.actionResolve(ctx, metadata, &R.RuleActionResolve{
|
||||||
Strategy: C.DomainStrategy(metadata.InboundOptions.DomainStrategy),
|
Strategy: C.DomainStrategy(metadata.InboundOptions.DomainStrategy),
|
||||||
})
|
})
|
||||||
if fatalErr != nil {
|
if fatalErr != nil {
|
||||||
@ -394,11 +394,11 @@ match:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var routeOptions *rule.RuleActionRouteOptions
|
var routeOptions *R.RuleActionRouteOptions
|
||||||
switch action := currentRule.Action().(type) {
|
switch action := currentRule.Action().(type) {
|
||||||
case *rule.RuleActionRoute:
|
case *R.RuleActionRoute:
|
||||||
routeOptions = &action.RuleActionRouteOptions
|
routeOptions = &action.RuleActionRouteOptions
|
||||||
case *rule.RuleActionRouteOptions:
|
case *R.RuleActionRouteOptions:
|
||||||
routeOptions = action
|
routeOptions = action
|
||||||
}
|
}
|
||||||
if routeOptions != nil {
|
if routeOptions != nil {
|
||||||
@ -451,7 +451,7 @@ match:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch action := currentRule.Action().(type) {
|
switch action := currentRule.Action().(type) {
|
||||||
case *rule.RuleActionSniff:
|
case *R.RuleActionSniff:
|
||||||
if !preMatch {
|
if !preMatch {
|
||||||
newBuffer, newPacketBuffers, newErr := r.actionSniff(ctx, metadata, action, inputConn, inputPacketConn, buffers)
|
newBuffer, newPacketBuffers, newErr := r.actionSniff(ctx, metadata, action, inputConn, inputPacketConn, buffers)
|
||||||
if newErr != nil {
|
if newErr != nil {
|
||||||
@ -468,7 +468,7 @@ match:
|
|||||||
selectedRuleIndex = currentRuleIndex
|
selectedRuleIndex = currentRuleIndex
|
||||||
break match
|
break match
|
||||||
}
|
}
|
||||||
case *rule.RuleActionResolve:
|
case *R.RuleActionResolve:
|
||||||
fatalErr = r.actionResolve(ctx, metadata, action)
|
fatalErr = r.actionResolve(ctx, metadata, action)
|
||||||
if fatalErr != nil {
|
if fatalErr != nil {
|
||||||
return
|
return
|
||||||
@ -488,7 +488,7 @@ match:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Router) actionSniff(
|
func (r *Router) actionSniff(
|
||||||
ctx context.Context, metadata *adapter.InboundContext, action *rule.RuleActionSniff,
|
ctx context.Context, metadata *adapter.InboundContext, action *R.RuleActionSniff,
|
||||||
inputConn net.Conn, inputPacketConn N.PacketConn, inputBuffers []*buf.Buffer,
|
inputConn net.Conn, inputPacketConn N.PacketConn, inputBuffers []*buf.Buffer,
|
||||||
) (buffer *buf.Buffer, packetBuffers []*N.PacketBuffer, fatalErr error) {
|
) (buffer *buf.Buffer, packetBuffers []*N.PacketBuffer, fatalErr error) {
|
||||||
if sniff.Skip(metadata) {
|
if sniff.Skip(metadata) {
|
||||||
@ -649,7 +649,7 @@ func (r *Router) actionSniff(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Router) actionResolve(ctx context.Context, metadata *adapter.InboundContext, action *rule.RuleActionResolve) error {
|
func (r *Router) actionResolve(ctx context.Context, metadata *adapter.InboundContext, action *R.RuleActionResolve) error {
|
||||||
if metadata.Destination.IsFqdn() {
|
if metadata.Destination.IsFqdn() {
|
||||||
var transport adapter.DNSTransport
|
var transport adapter.DNSTransport
|
||||||
if action.Server != "" {
|
if action.Server != "" {
|
||||||
|
@ -2,6 +2,7 @@ package rule
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -284,6 +285,23 @@ func (r *RuleActionDirect) String() string {
|
|||||||
return "direct" + r.description
|
return "direct" + r.description
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RejectedError struct {
|
||||||
|
Cause error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RejectedError) Error() string {
|
||||||
|
return "rejected"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RejectedError) Unwrap() error {
|
||||||
|
return r.Cause
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsRejected(err error) bool {
|
||||||
|
var rejected *RejectedError
|
||||||
|
return errors.As(err, &rejected)
|
||||||
|
}
|
||||||
|
|
||||||
type RuleActionReject struct {
|
type RuleActionReject struct {
|
||||||
Method string
|
Method string
|
||||||
NoDrop bool
|
NoDrop bool
|
||||||
@ -307,9 +325,9 @@ func (r *RuleActionReject) Error(ctx context.Context) error {
|
|||||||
var returnErr error
|
var returnErr error
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case C.RuleActionRejectMethodDefault:
|
case C.RuleActionRejectMethodDefault:
|
||||||
returnErr = syscall.ECONNREFUSED
|
returnErr = &RejectedError{syscall.ECONNREFUSED}
|
||||||
case C.RuleActionRejectMethodDrop:
|
case C.RuleActionRejectMethodDrop:
|
||||||
return tun.ErrDrop
|
return &RejectedError{tun.ErrDrop}
|
||||||
default:
|
default:
|
||||||
panic(F.ToString("unknown reject method: ", r.Method))
|
panic(F.ToString("unknown reject method: ", r.Method))
|
||||||
}
|
}
|
||||||
@ -327,7 +345,7 @@ func (r *RuleActionReject) Error(ctx context.Context) error {
|
|||||||
if ctx != nil {
|
if ctx != nil {
|
||||||
r.logger.DebugContext(ctx, "dropped due to flooding")
|
r.logger.DebugContext(ctx, "dropped due to flooding")
|
||||||
}
|
}
|
||||||
return tun.ErrDrop
|
return &RejectedError{tun.ErrDrop}
|
||||||
}
|
}
|
||||||
return returnErr
|
return returnErr
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user