mirror of
https://github.com/daeuniverse/dae.git
synced 2024-12-23 01:14:46 +07:00
optimize: remove rush-answer detector because it does always work in all districts
This commit is contained in:
parent
f915b47a9a
commit
12febe94cf
@ -10,6 +10,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mzz2017/softwind/netproxy"
|
"github.com/mzz2017/softwind/netproxy"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/net/dns/dnsmessage"
|
"golang.org/x/net/dns/dnsmessage"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"sync"
|
"sync"
|
||||||
@ -21,6 +22,17 @@ type Ip46 struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ResolveIp46(ctx context.Context, dialer netproxy.Dialer, dns netip.AddrPort, host string, tcp bool, race bool) (ipv46 *Ip46, err error) {
|
func ResolveIp46(ctx context.Context, dialer netproxy.Dialer, dns netip.AddrPort, host string, tcp bool, race bool) (ipv46 *Ip46, err error) {
|
||||||
|
var log *logrus.Logger
|
||||||
|
if _log := ctx.Value("logger"); _log != nil {
|
||||||
|
log = _log.(*logrus.Logger)
|
||||||
|
defer func() {
|
||||||
|
if err == nil {
|
||||||
|
log.Tracef("ResolveIp46 %v using %v: A(%v) AAAA(%v)", host, systemDns, ipv46.Ip4, ipv46.Ip6)
|
||||||
|
} else {
|
||||||
|
log.Tracef("ResolveIp46 %v using %v: %v", host, systemDns, err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(2)
|
wg.Add(2)
|
||||||
var err4, err6 error
|
var err4, err6 error
|
||||||
|
@ -7,9 +7,9 @@ package dialer
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/daeuniverse/dae/common/consts"
|
||||||
"github.com/mzz2017/softwind/pkg/fastrand"
|
"github.com/mzz2017/softwind/pkg/fastrand"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/daeuniverse/dae/common/consts"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -138,10 +138,8 @@ func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
|
|||||||
// Dialer: not alive -> alive.
|
// Dialer: not alive -> alive.
|
||||||
if index == -NotAlive {
|
if index == -NotAlive {
|
||||||
a.log.WithFields(logrus.Fields{
|
a.log.WithFields(logrus.Fields{
|
||||||
"dialer": dialer.property.Name,
|
"group": a.dialerGroupName,
|
||||||
"group": a.dialerGroupName,
|
}).Infof("[NOT ALIVE --%v-> ALIVE] %v", a.CheckTyp.String(), dialer.property.Name)
|
||||||
"network": a.CheckTyp.StringWithoutDns(),
|
|
||||||
}).Infoln("NOT ALIVE -> ALIVE:")
|
|
||||||
}
|
}
|
||||||
a.dialerToIndex[dialer] = len(a.inorderedAliveDialerSet)
|
a.dialerToIndex[dialer] = len(a.inorderedAliveDialerSet)
|
||||||
a.inorderedAliveDialerSet = append(a.inorderedAliveDialerSet, dialer)
|
a.inorderedAliveDialerSet = append(a.inorderedAliveDialerSet, dialer)
|
||||||
@ -151,10 +149,8 @@ func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
|
|||||||
if index >= 0 {
|
if index >= 0 {
|
||||||
// Dialer: alive -> not alive.
|
// Dialer: alive -> not alive.
|
||||||
a.log.WithFields(logrus.Fields{
|
a.log.WithFields(logrus.Fields{
|
||||||
"dialer": dialer.property.Name,
|
"group": a.dialerGroupName,
|
||||||
"group": a.dialerGroupName,
|
}).Infof("[ALIVE --%v-> NOT ALIVE] %v", a.CheckTyp.String(), dialer.property.Name)
|
||||||
"network": a.CheckTyp.StringWithoutDns(),
|
|
||||||
}).Infoln("ALIVE -> NOT ALIVE:")
|
|
||||||
// Remove the dialer from inorderedAliveDialerSet.
|
// Remove the dialer from inorderedAliveDialerSet.
|
||||||
if index >= len(a.inorderedAliveDialerSet) {
|
if index >= len(a.inorderedAliveDialerSet) {
|
||||||
a.log.Panicf("index:%v >= len(a.inorderedAliveDialerSet):%v", index, len(a.inorderedAliveDialerSet))
|
a.log.Panicf("index:%v >= len(a.inorderedAliveDialerSet):%v", index, len(a.inorderedAliveDialerSet))
|
||||||
|
@ -167,6 +167,7 @@ func ParseCheckDnsOption(ctx context.Context, dnsHostPort string) (opt *CheckDns
|
|||||||
type TcpCheckOptionRaw struct {
|
type TcpCheckOptionRaw struct {
|
||||||
opt *TcpCheckOption
|
opt *TcpCheckOption
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
Log *logrus.Logger
|
||||||
Raw string
|
Raw string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,6 +177,7 @@ func (c *TcpCheckOptionRaw) Option() (opt *TcpCheckOption, err error) {
|
|||||||
if c.opt == nil {
|
if c.opt == nil {
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(context.TODO(), 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
ctx = context.WithValue(ctx, "logger", c.Log)
|
||||||
tcpCheckOption, err := ParseTcpCheckOption(ctx, c.Raw)
|
tcpCheckOption, err := ParseTcpCheckOption(ctx, c.Raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse tcp_check_url: %w", err)
|
return nil, fmt.Errorf("failed to parse tcp_check_url: %w", err)
|
||||||
@ -238,6 +240,7 @@ func (d *Dialer) aliveBackground() {
|
|||||||
if !opt.Ip4.IsValid() {
|
if !opt.Ip4.IsValid() {
|
||||||
d.Log.WithFields(logrus.Fields{
|
d.Log.WithFields(logrus.Fields{
|
||||||
"link": d.TcpCheckOptionRaw.Raw,
|
"link": d.TcpCheckOptionRaw.Raw,
|
||||||
|
"dialer": d.property.Name,
|
||||||
"network": typ.String(),
|
"network": typ.String(),
|
||||||
}).Debugln("Skip check due to no DNS record.")
|
}).Debugln("Skip check due to no DNS record.")
|
||||||
return false, nil
|
return false, nil
|
||||||
@ -259,6 +262,7 @@ func (d *Dialer) aliveBackground() {
|
|||||||
if !opt.Ip6.IsValid() {
|
if !opt.Ip6.IsValid() {
|
||||||
d.Log.WithFields(logrus.Fields{
|
d.Log.WithFields(logrus.Fields{
|
||||||
"link": d.TcpCheckOptionRaw.Raw,
|
"link": d.TcpCheckOptionRaw.Raw,
|
||||||
|
"dialer": d.property.Name,
|
||||||
"network": typ.String(),
|
"network": typ.String(),
|
||||||
}).Debugln("Skip check due to no DNS record.")
|
}).Debugln("Skip check due to no DNS record.")
|
||||||
return false, nil
|
return false, nil
|
||||||
@ -280,6 +284,7 @@ func (d *Dialer) aliveBackground() {
|
|||||||
if !opt.Ip4.IsValid() {
|
if !opt.Ip4.IsValid() {
|
||||||
d.Log.WithFields(logrus.Fields{
|
d.Log.WithFields(logrus.Fields{
|
||||||
"link": d.CheckDnsOptionRaw.Raw,
|
"link": d.CheckDnsOptionRaw.Raw,
|
||||||
|
"dialer": d.property.Name,
|
||||||
"network": typ.String(),
|
"network": typ.String(),
|
||||||
}).Debugln("Skip check due to no DNS record.")
|
}).Debugln("Skip check due to no DNS record.")
|
||||||
return false, nil
|
return false, nil
|
||||||
@ -301,6 +306,7 @@ func (d *Dialer) aliveBackground() {
|
|||||||
if !opt.Ip6.IsValid() {
|
if !opt.Ip6.IsValid() {
|
||||||
d.Log.WithFields(logrus.Fields{
|
d.Log.WithFields(logrus.Fields{
|
||||||
"link": d.CheckDnsOptionRaw.Raw,
|
"link": d.CheckDnsOptionRaw.Raw,
|
||||||
|
"dialer": d.property.Name,
|
||||||
"network": typ.String(),
|
"network": typ.String(),
|
||||||
}).Debugln("Skip check due to no DNS record.")
|
}).Debugln("Skip check due to no DNS record.")
|
||||||
return false, nil
|
return false, nil
|
||||||
@ -523,9 +529,16 @@ func (d *Dialer) HttpCheck(ctx context.Context, u *netutils.URL, ip netip.Addr)
|
|||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
// Judge the status code.
|
// Judge the status code.
|
||||||
if page := path.Base(req.URL.Path); strings.HasPrefix(page, "generate_") {
|
if page := path.Base(req.URL.Path); strings.HasPrefix(page, "generate_") {
|
||||||
return strconv.Itoa(resp.StatusCode) == strings.TrimPrefix(page, "generate_"), nil
|
if strconv.Itoa(resp.StatusCode) != strings.TrimPrefix(page, "generate_") {
|
||||||
|
return false, fmt.Errorf("unexpected status code: %v", resp.StatusCode)
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
} else {
|
||||||
|
if resp.StatusCode < 200 || resp.StatusCode >= 500 {
|
||||||
|
return false, fmt.Errorf("bad status code: %v", resp.StatusCode)
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
}
|
}
|
||||||
return resp.StatusCode >= 200 && resp.StatusCode < 500, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dialer) DnsCheck(ctx context.Context, dns netip.AddrPort, tcp bool) (ok bool, err error) {
|
func (d *Dialer) DnsCheck(ctx context.Context, dns netip.AddrPort, tcp bool) (ok bool, err error) {
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
package outbound
|
package outbound
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/mzz2017/softwind/pkg/fastrand"
|
|
||||||
"github.com/daeuniverse/dae/common/consts"
|
"github.com/daeuniverse/dae/common/consts"
|
||||||
"github.com/daeuniverse/dae/component/outbound/dialer"
|
"github.com/daeuniverse/dae/component/outbound/dialer"
|
||||||
"github.com/daeuniverse/dae/pkg/logger"
|
"github.com/daeuniverse/dae/pkg/logger"
|
||||||
|
"github.com/mzz2017/softwind/pkg/fastrand"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -43,7 +43,7 @@ func TestDialerGroup_Select_Fixed(t *testing.T) {
|
|||||||
g := NewDialerGroup(option, "test-group", dialers, DialerSelectionPolicy{
|
g := NewDialerGroup(option, "test-group", dialers, DialerSelectionPolicy{
|
||||||
Policy: consts.DialerSelectionPolicy_Fixed,
|
Policy: consts.DialerSelectionPolicy_Fixed,
|
||||||
FixedIndex: fixedIndex,
|
FixedIndex: fixedIndex,
|
||||||
}, func(alive bool, networkType *dialer.NetworkType) {})
|
}, func(alive bool, networkType *dialer.NetworkType, isInit bool) {})
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
d, _, err := g.Select(TestNetworkType)
|
d, _, err := g.Select(TestNetworkType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -90,7 +90,7 @@ func TestDialerGroup_Select_MinLastLatency(t *testing.T) {
|
|||||||
}
|
}
|
||||||
g := NewDialerGroup(option, "test-group", dialers, DialerSelectionPolicy{
|
g := NewDialerGroup(option, "test-group", dialers, DialerSelectionPolicy{
|
||||||
Policy: consts.DialerSelectionPolicy_MinLastLatency,
|
Policy: consts.DialerSelectionPolicy_MinLastLatency,
|
||||||
}, func(alive bool, networkType *dialer.NetworkType) {})
|
}, func(alive bool, networkType *dialer.NetworkType, isInit bool) {})
|
||||||
|
|
||||||
// Test 1000 times.
|
// Test 1000 times.
|
||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 1000; i++ {
|
||||||
@ -155,7 +155,7 @@ func TestDialerGroup_Select_Random(t *testing.T) {
|
|||||||
}
|
}
|
||||||
g := NewDialerGroup(option, "test-group", dialers, DialerSelectionPolicy{
|
g := NewDialerGroup(option, "test-group", dialers, DialerSelectionPolicy{
|
||||||
Policy: consts.DialerSelectionPolicy_Random,
|
Policy: consts.DialerSelectionPolicy_Random,
|
||||||
}, func(alive bool, networkType *dialer.NetworkType) {})
|
}, func(alive bool, networkType *dialer.NetworkType, isInit bool) {})
|
||||||
count := make([]int, len(dialers))
|
count := make([]int, len(dialers))
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
d, _, err := g.Select(TestNetworkType)
|
d, _, err := g.Select(TestNetworkType)
|
||||||
@ -195,7 +195,7 @@ func TestDialerGroup_SetAlive(t *testing.T) {
|
|||||||
}
|
}
|
||||||
g := NewDialerGroup(option, "test-group", dialers, DialerSelectionPolicy{
|
g := NewDialerGroup(option, "test-group", dialers, DialerSelectionPolicy{
|
||||||
Policy: consts.DialerSelectionPolicy_Random,
|
Policy: consts.DialerSelectionPolicy_Random,
|
||||||
}, func(alive bool, networkType *dialer.NetworkType) {})
|
}, func(alive bool, networkType *dialer.NetworkType, isInit bool) {})
|
||||||
zeroTarget := 3
|
zeroTarget := 3
|
||||||
g.MustGetAliveDialerSet(TestNetworkType).NotifyLatencyChange(dialers[zeroTarget], false)
|
g.MustGetAliveDialerSet(TestNetworkType).NotifyLatencyChange(dialers[zeroTarget], false)
|
||||||
count := make([]int, len(dialers))
|
count := make([]int, len(dialers))
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
package domain_matcher
|
package domain_matcher
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"github.com/daeuniverse/dae/common/consts"
|
"github.com/daeuniverse/dae/common/consts"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
@ -21,7 +21,7 @@ func TestAhocorasickSlimtrie(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
bf := NewBruteforce(consts.MaxMatchSetLen)
|
bf := NewBruteforce(consts.MaxMatchSetLen)
|
||||||
actrie := NewAhocorasickSlimtrie(consts.MaxMatchSetLen)
|
actrie := NewAhocorasickSlimtrie(logrus.StandardLogger(), consts.MaxMatchSetLen)
|
||||||
for _, domains := range simulatedDomainSet {
|
for _, domains := range simulatedDomainSet {
|
||||||
bf.AddSet(domains.RuleIndex, domains.Domains, domains.Key)
|
bf.AddSet(domains.RuleIndex, domains.Domains, domains.Key)
|
||||||
actrie.AddSet(domains.RuleIndex, domains.Domains, domains.Key)
|
actrie.AddSet(domains.RuleIndex, domains.Domains, domains.Key)
|
||||||
|
@ -220,7 +220,7 @@ func NewControlPlane(
|
|||||||
}
|
}
|
||||||
option := &dialer.GlobalOption{
|
option := &dialer.GlobalOption{
|
||||||
Log: log,
|
Log: log,
|
||||||
TcpCheckOptionRaw: dialer.TcpCheckOptionRaw{Raw: global.TcpCheckUrl},
|
TcpCheckOptionRaw: dialer.TcpCheckOptionRaw{Raw: global.TcpCheckUrl, Log: log},
|
||||||
CheckDnsOptionRaw: dialer.CheckDnsOptionRaw{Raw: global.UdpCheckDns},
|
CheckDnsOptionRaw: dialer.CheckDnsOptionRaw{Raw: global.UdpCheckDns},
|
||||||
CheckInterval: global.CheckInterval,
|
CheckInterval: global.CheckInterval,
|
||||||
CheckTolerance: global.CheckTolerance,
|
CheckTolerance: global.CheckTolerance,
|
||||||
|
@ -312,10 +312,11 @@ func (c *DnsController) Handle_(dnsMessage *dnsmessage.Message, req *udpRequest)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure there is additional record OPT in the request to filter DNS rush-answer in the response process.
|
//// NOTICE: Rush-answer detector was removed because it does not always work in all districts.
|
||||||
// Because rush-answer has no resp OPT. We can distinguish them from multiple responses.
|
//// Make sure there is additional record OPT in the request to filter DNS rush-answer in the response process.
|
||||||
// Note that additional record OPT may not be supported by home router either.
|
//// Because rush-answer has no resp OPT. We can distinguish them from multiple responses.
|
||||||
_, _ = EnsureAdditionalOpt(dnsMessage, true)
|
//// Note that additional record OPT may not be supported by home router either.
|
||||||
|
//_, _ = EnsureAdditionalOpt(dnsMessage, true)
|
||||||
|
|
||||||
// Route request.
|
// Route request.
|
||||||
upstream, err := c.routing.RequestSelect(dnsMessage)
|
upstream, err := c.routing.RequestSelect(dnsMessage)
|
||||||
@ -382,13 +383,17 @@ func (c *DnsController) dialSend(req *udpRequest, data []byte, id uint16, upstre
|
|||||||
|
|
||||||
// dnsRespHandler caches dns response and check rush answers.
|
// dnsRespHandler caches dns response and check rush answers.
|
||||||
dnsRespHandler := c.DnsRespHandlerFactory(func(from netip.AddrPort) bool {
|
dnsRespHandler := c.DnsRespHandlerFactory(func(from netip.AddrPort) bool {
|
||||||
// We only validate rush-ans when outbound is direct and pkt does not send to a home device.
|
//// NOTICE: Rush-answer detector was removed because it does not always work in all districts.
|
||||||
// Because additional record OPT may not be supported by home router.
|
//// We only validate rush-ans when outbound is direct and pkt does not send to a home device.
|
||||||
// So se should trust home devices even if they make rush-answer (or looks like).
|
//// Because additional record OPT may not be supported by home router.
|
||||||
return dialArgument.bestDialer.Property().Name == "direct" &&
|
//// So se should trust home devices even if they make rush-answer (or looks like).
|
||||||
!from.Addr().IsPrivate() &&
|
//return dialArgument.bestDialer.Property().Name == "direct" &&
|
||||||
!from.Addr().IsLoopback() &&
|
// !from.Addr().IsPrivate() &&
|
||||||
!from.Addr().IsUnspecified()
|
// !from.Addr().IsLoopback() &&
|
||||||
|
// !from.Addr().IsUnspecified()
|
||||||
|
|
||||||
|
// Do not validate rush-answer.
|
||||||
|
return false
|
||||||
})
|
})
|
||||||
// Dial and send.
|
// Dial and send.
|
||||||
var respMsg *dnsmessage.Message
|
var respMsg *dnsmessage.Message
|
||||||
@ -456,12 +461,12 @@ func (c *DnsController) dialSend(req *udpRequest, data []byte, id uint16, upstre
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read from: %v (dialer: %v): %w", dialArgument.bestTarget, dialArgument.bestDialer.Property().Name, err)
|
return fmt.Errorf("failed to read from: %v (dialer: %v): %w", dialArgument.bestTarget, dialArgument.bestDialer.Property().Name, err)
|
||||||
}
|
}
|
||||||
cancelDnsReqCtx()
|
|
||||||
respMsg, err = dnsRespHandler(respBuf[:n], dialArgument.bestTarget)
|
respMsg, err = dnsRespHandler(respBuf[:n], dialArgument.bestTarget)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if respMsg != nil {
|
if respMsg != nil {
|
||||||
|
cancelDnsReqCtx()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user