mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-04-12 01:57:18 +10:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f63091d14d | ||
|
|
1c4a01ee90 | ||
|
|
4d7f99310c | ||
|
|
6fc511f56e | ||
|
|
d18d2b352a | ||
|
|
534128bba9 | ||
|
|
736a7368c6 | ||
|
|
e7a9c90213 |
Submodule clients/android updated: 661fc3cc2a...eb87216961
@@ -144,7 +144,11 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m
|
||||
if c.cache != nil {
|
||||
cond, loaded := c.cacheLock.LoadOrStore(question, make(chan struct{}))
|
||||
if loaded {
|
||||
<-cond
|
||||
select {
|
||||
case <-cond:
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
} else {
|
||||
defer func() {
|
||||
c.cacheLock.Delete(question)
|
||||
@@ -154,7 +158,11 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m
|
||||
} else if c.transportCache != nil {
|
||||
cond, loaded := c.transportCacheLock.LoadOrStore(question, make(chan struct{}))
|
||||
if loaded {
|
||||
<-cond
|
||||
select {
|
||||
case <-cond:
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
} else {
|
||||
defer func() {
|
||||
c.transportCacheLock.Delete(question)
|
||||
|
||||
@@ -378,9 +378,11 @@ func (r *Router) Lookup(ctx context.Context, domain string, options adapter.DNSQ
|
||||
case *R.RuleActionReject:
|
||||
return nil, &R.RejectedError{Cause: action.Error(ctx)}
|
||||
case *R.RuleActionPredefined:
|
||||
responseAddrs = nil
|
||||
if action.Rcode != mDNS.RcodeSuccess {
|
||||
err = RcodeError(action.Rcode)
|
||||
} else {
|
||||
err = nil
|
||||
for _, answer := range action.Answer {
|
||||
switch record := answer.(type) {
|
||||
case *mDNS.A:
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
icon: material/alert-decagram
|
||||
---
|
||||
|
||||
#### 1.12.22
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.12.21
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
#### 1.12.20
|
||||
|
||||
* Fixes and improvements
|
||||
|
||||
2
go.mod
2
go.mod
@@ -29,7 +29,7 @@ require (
|
||||
github.com/sagernet/quic-go v0.52.0-sing-box-mod.3
|
||||
github.com/sagernet/sing v0.7.18
|
||||
github.com/sagernet/sing-mux v0.3.4
|
||||
github.com/sagernet/sing-quic v0.5.2
|
||||
github.com/sagernet/sing-quic v0.5.3
|
||||
github.com/sagernet/sing-shadowsocks v0.2.8
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.1
|
||||
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11
|
||||
|
||||
4
go.sum
4
go.sum
@@ -169,8 +169,8 @@ github.com/sagernet/sing v0.7.18 h1:iZHkaru1/MoHugx3G+9S3WG4owMewKO/KvieE2Pzk4E=
|
||||
github.com/sagernet/sing v0.7.18/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing-mux v0.3.4 h1:ZQplKl8MNXutjzbMVtWvWG31fohhgOfCuUZR4dVQ8+s=
|
||||
github.com/sagernet/sing-mux v0.3.4/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk=
|
||||
github.com/sagernet/sing-quic v0.5.2 h1:I3vlfRImhr0uLwRS3b3ib70RMG9FcXtOKKUDz3eKRWc=
|
||||
github.com/sagernet/sing-quic v0.5.2/go.mod h1:evP1e++ZG8TJHVV5HudXV4vWeYzGfCdF4HwSJZcdqkI=
|
||||
github.com/sagernet/sing-quic v0.5.3 h1:K937DKJN98xqyztijRkLJqbBfyV4rEZcYxFyP3EBikU=
|
||||
github.com/sagernet/sing-quic v0.5.3/go.mod h1:evP1e++ZG8TJHVV5HudXV4vWeYzGfCdF4HwSJZcdqkI=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.8 h1:PURj5PRoAkqeHh2ZW205RWzN9E9RtKCVCzByXruQWfE=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.8/go.mod h1:lo7TWEMDcN5/h5B8S0ew+r78ZODn6SwVaFhvB6H+PTI=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnqqs2gQ2/Qioo=
|
||||
|
||||
@@ -95,6 +95,7 @@ func (p *paddingConn) writeWithPadding(writer io.Writer, data []byte) (n int, er
|
||||
binary.BigEndian.PutUint16(header, uint16(len(data)))
|
||||
header[2] = byte(paddingSize)
|
||||
common.Must1(buffer.Write(data))
|
||||
buffer.Extend(paddingSize)
|
||||
_, err = writer.Write(buffer.Bytes())
|
||||
if err == nil {
|
||||
n = len(data)
|
||||
|
||||
@@ -107,9 +107,7 @@ func (r *abstractDefaultRule) Match(metadata *adapter.InboundContext) bool {
|
||||
}
|
||||
|
||||
for _, item := range r.items {
|
||||
if _, isRuleSet := item.(*RuleSetItem); !isRuleSet {
|
||||
metadata.DidMatch = true
|
||||
}
|
||||
metadata.DidMatch = true
|
||||
if !item.Match(metadata) {
|
||||
return r.invert
|
||||
}
|
||||
|
||||
157
route/rule/rule_abstract_test.go
Normal file
157
route/rule/rule_abstract_test.go
Normal file
@@ -0,0 +1,157 @@
|
||||
package rule
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing/common/x/list"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"go4.org/netipx"
|
||||
)
|
||||
|
||||
type fakeRuleSet struct {
|
||||
matched bool
|
||||
}
|
||||
|
||||
func (f *fakeRuleSet) Name() string {
|
||||
return "fake-rule-set"
|
||||
}
|
||||
|
||||
func (f *fakeRuleSet) StartContext(context.Context, *adapter.HTTPStartContext) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeRuleSet) PostStart() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeRuleSet) Metadata() adapter.RuleSetMetadata {
|
||||
return adapter.RuleSetMetadata{}
|
||||
}
|
||||
|
||||
func (f *fakeRuleSet) ExtractIPSet() []*netipx.IPSet {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeRuleSet) IncRef() {}
|
||||
|
||||
func (f *fakeRuleSet) DecRef() {}
|
||||
|
||||
func (f *fakeRuleSet) Cleanup() {}
|
||||
|
||||
func (f *fakeRuleSet) RegisterCallback(adapter.RuleSetUpdateCallback) *list.Element[adapter.RuleSetUpdateCallback] {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeRuleSet) UnregisterCallback(*list.Element[adapter.RuleSetUpdateCallback]) {}
|
||||
|
||||
func (f *fakeRuleSet) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeRuleSet) Match(*adapter.InboundContext) bool {
|
||||
return f.matched
|
||||
}
|
||||
|
||||
func (f *fakeRuleSet) String() string {
|
||||
return "fake-rule-set"
|
||||
}
|
||||
|
||||
type fakeRuleItem struct {
|
||||
matched bool
|
||||
}
|
||||
|
||||
func (f *fakeRuleItem) Match(*adapter.InboundContext) bool {
|
||||
return f.matched
|
||||
}
|
||||
|
||||
func (f *fakeRuleItem) String() string {
|
||||
return "fake-rule-item"
|
||||
}
|
||||
|
||||
func newRuleSetOnlyRule(ruleSetMatched bool, invert bool) *DefaultRule {
|
||||
ruleSetItem := &RuleSetItem{
|
||||
setList: []adapter.RuleSet{&fakeRuleSet{matched: ruleSetMatched}},
|
||||
}
|
||||
return &DefaultRule{
|
||||
abstractDefaultRule: abstractDefaultRule{
|
||||
items: []RuleItem{ruleSetItem},
|
||||
allItems: []RuleItem{ruleSetItem},
|
||||
invert: invert,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func newSingleItemRule(matched bool) *DefaultRule {
|
||||
item := &fakeRuleItem{matched: matched}
|
||||
return &DefaultRule{
|
||||
abstractDefaultRule: abstractDefaultRule{
|
||||
items: []RuleItem{item},
|
||||
allItems: []RuleItem{item},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestAbstractDefaultRule_RuleSetOnly_InvertFalse(t *testing.T) {
|
||||
t.Parallel()
|
||||
require.True(t, newRuleSetOnlyRule(true, false).Match(&adapter.InboundContext{}))
|
||||
require.False(t, newRuleSetOnlyRule(false, false).Match(&adapter.InboundContext{}))
|
||||
}
|
||||
|
||||
func TestAbstractDefaultRule_RuleSetOnly_InvertTrue(t *testing.T) {
|
||||
t.Parallel()
|
||||
require.False(t, newRuleSetOnlyRule(true, true).Match(&adapter.InboundContext{}))
|
||||
require.True(t, newRuleSetOnlyRule(false, true).Match(&adapter.InboundContext{}))
|
||||
}
|
||||
|
||||
func TestAbstractLogicalRule_And_WithRuleSetInvert(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := []struct {
|
||||
name string
|
||||
aMatched bool
|
||||
ruleSetBMatch bool
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "A true B true",
|
||||
aMatched: true,
|
||||
ruleSetBMatch: true,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "A true B false",
|
||||
aMatched: true,
|
||||
ruleSetBMatch: false,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "A false B true",
|
||||
aMatched: false,
|
||||
ruleSetBMatch: true,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "A false B false",
|
||||
aMatched: false,
|
||||
ruleSetBMatch: false,
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
logicalRule := &abstractLogicalRule{
|
||||
mode: C.LogicalTypeAnd,
|
||||
rules: []adapter.HeadlessRule{
|
||||
newSingleItemRule(testCase.aMatched),
|
||||
newRuleSetOnlyRule(testCase.ruleSetBMatch, true),
|
||||
},
|
||||
}
|
||||
require.Equal(t, testCase.expected, logicalRule.Match(&adapter.InboundContext{}))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,7 @@ func (w *systemDevice) Start() error {
|
||||
w.options.Logger.Info("started at ", w.options.Name)
|
||||
w.device = tunInterface
|
||||
batchTUN, isBatchTUN := tunInterface.(tun.LinuxTUN)
|
||||
if isBatchTUN {
|
||||
if isBatchTUN && batchTUN.BatchSize() > 1 {
|
||||
w.batchDevice = batchTUN
|
||||
}
|
||||
w.events <- wgTun.EventUp
|
||||
|
||||
Reference in New Issue
Block a user