mirror of
https://github.com/daeuniverse/dae.git
synced 2024-12-23 01:04:40 +07:00
optimize(dial_mode): cache for real domain
This commit is contained in:
parent
9224d96521
commit
f061ca7884
@ -12,6 +12,7 @@ import (
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"github.com/mzz2017/softwind/pkg/fastrand"
|
||||
"github.com/mzz2017/softwind/pool"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
"io"
|
||||
"math"
|
||||
@ -105,8 +106,10 @@ func ResolveNS(ctx context.Context, d netproxy.Dialer, dns netip.AddrPort, host
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logrus.Println(host, len(resources))
|
||||
for _, ans := range resources {
|
||||
if ans.Header.Type != typ {
|
||||
logrus.Println(host, ans.Header.Type)
|
||||
continue
|
||||
}
|
||||
ns, ok := ans.Body.(*dnsmessage.NSResource)
|
||||
@ -147,7 +150,6 @@ func resolve(ctx context.Context, d netproxy.Dialer, dns netip.AddrPort, host st
|
||||
return nil, nil
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("only support to lookup A/AAAA record")
|
||||
}
|
||||
// Build DNS req.
|
||||
builder := dnsmessage.NewBuilder(nil, dnsmessage.Header{
|
||||
|
@ -7,9 +7,12 @@ package netutils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/mzz2017/softwind/netproxy"
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
"net/netip"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Ip46 struct {
|
||||
@ -17,20 +20,59 @@ type Ip46 struct {
|
||||
Ip6 netip.Addr
|
||||
}
|
||||
|
||||
func ResolveIp46(ctx context.Context, dialer netproxy.Dialer, dns netip.AddrPort, host string, tcp bool) (ipv46 *Ip46, err error) {
|
||||
addrs4, err := ResolveNetip(ctx, dialer, dns, host, dnsmessage.TypeA, tcp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(addrs4) == 0 {
|
||||
addrs4 = []netip.Addr{{}}
|
||||
}
|
||||
addrs6, err := ResolveNetip(ctx, dialer, dns, host, dnsmessage.TypeAAAA, tcp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(addrs6) == 0 {
|
||||
addrs6 = []netip.Addr{{}}
|
||||
func ResolveIp46(ctx context.Context, dialer netproxy.Dialer, dns netip.AddrPort, host string, tcp bool, race bool) (ipv46 *Ip46, err error) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
var err4, err6 error
|
||||
var addrs4, addrs6 []netip.Addr
|
||||
ctx4, cancel4 := context.WithCancel(ctx)
|
||||
ctx6, cancel6 := context.WithCancel(ctx)
|
||||
go func() {
|
||||
defer func() {
|
||||
wg.Done()
|
||||
cancel4()
|
||||
if race {
|
||||
cancel6()
|
||||
}
|
||||
}()
|
||||
var e error
|
||||
addrs4, e = ResolveNetip(ctx4, dialer, dns, host, dnsmessage.TypeA, tcp)
|
||||
if err != nil && !errors.Is(e, context.Canceled) {
|
||||
err4 = e
|
||||
return
|
||||
}
|
||||
if len(addrs4) == 0 {
|
||||
addrs4 = []netip.Addr{{}}
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
defer func() {
|
||||
wg.Done()
|
||||
cancel6()
|
||||
if race {
|
||||
cancel4()
|
||||
}
|
||||
}()
|
||||
var e error
|
||||
addrs6, e = ResolveNetip(ctx6, dialer, dns, host, dnsmessage.TypeAAAA, tcp)
|
||||
if err != nil && !errors.Is(e, context.Canceled) {
|
||||
err6 = e
|
||||
return
|
||||
}
|
||||
if len(addrs6) == 0 {
|
||||
addrs6 = []netip.Addr{{}}
|
||||
}
|
||||
}()
|
||||
wg.Wait()
|
||||
if err4 != nil || err6 != nil {
|
||||
if err4 != nil && err6 != nil {
|
||||
return nil, fmt.Errorf("%w: %v", err4, err6)
|
||||
}
|
||||
if err4 != nil {
|
||||
return nil, err4
|
||||
} else {
|
||||
return nil, err6
|
||||
}
|
||||
}
|
||||
return &Ip46{
|
||||
Ip4: addrs4[0],
|
||||
|
@ -79,7 +79,7 @@ func NewUpstream(ctx context.Context, upstream *url.URL) (up *Upstream, err erro
|
||||
}
|
||||
}()
|
||||
|
||||
ip46, err := netutils.ResolveIp46(ctx, direct.SymmetricDirect, systemDns, hostname, false)
|
||||
ip46, err := netutils.ResolveIp46(ctx, direct.SymmetricDirect, systemDns, hostname, false, false)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve dns_upstream: %w", err)
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ func ParseTcpCheckOption(ctx context.Context, rawURL string) (opt *TcpCheckOptio
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ip46, err := netutils.ResolveIp46(ctx, direct.SymmetricDirect, systemDns, u.Hostname(), false)
|
||||
ip46, err := netutils.ResolveIp46(ctx, direct.SymmetricDirect, systemDns, u.Hostname(), false, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -153,7 +153,7 @@ func ParseCheckDnsOption(ctx context.Context, dnsHostPort string) (opt *CheckDns
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("bad port: %v", err)
|
||||
}
|
||||
ip46, err := netutils.ResolveIp46(ctx, direct.SymmetricDirect, systemDns, host, false)
|
||||
ip46, err := netutils.ResolveIp46(ctx, direct.SymmetricDirect, systemDns, host, false, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ package control
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/bits-and-blooms/bloom/v3"
|
||||
"github.com/cilium/ebpf"
|
||||
"github.com/cilium/ebpf/rlimit"
|
||||
"github.com/mzz2017/softwind/pool"
|
||||
@ -56,6 +57,9 @@ type ControlPlane struct {
|
||||
|
||||
closed chan struct{}
|
||||
ready chan struct{}
|
||||
|
||||
muRealDomainSet sync.RWMutex
|
||||
realDomainSet *bloom.BloomFilter
|
||||
}
|
||||
|
||||
func NewControlPlane(
|
||||
@ -304,15 +308,19 @@ func NewControlPlane(
|
||||
}
|
||||
|
||||
plane := &ControlPlane{
|
||||
log: log,
|
||||
core: core,
|
||||
deferFuncs: deferFuncs,
|
||||
listenIp: "0.0.0.0",
|
||||
outbounds: outbounds,
|
||||
dialMode: dialMode,
|
||||
routingMatcher: routingMatcher,
|
||||
closed: make(chan struct{}),
|
||||
ready: make(chan struct{}),
|
||||
log: log,
|
||||
core: core,
|
||||
deferFuncs: deferFuncs,
|
||||
listenIp: "0.0.0.0",
|
||||
outbounds: outbounds,
|
||||
dnsController: nil,
|
||||
onceNetworkReady: sync.Once{},
|
||||
dialMode: dialMode,
|
||||
routingMatcher: routingMatcher,
|
||||
closed: make(chan struct{}),
|
||||
ready: make(chan struct{}),
|
||||
muRealDomainSet: sync.RWMutex{},
|
||||
realDomainSet: bloom.NewWithEstimates(2048, 0.001),
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
@ -455,14 +463,26 @@ func (c *ControlPlane) ChooseDialTarget(outbound consts.OutboundIndex, dst netip
|
||||
// Has A/AAAA records. It is a real domain.
|
||||
dialMode = consts.DialMode_Domain
|
||||
} else {
|
||||
// Lookup NS to make sure it is a real domain.
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), 5*time.Second)
|
||||
defer cancel()
|
||||
systemDns, err := netutils.SystemDns()
|
||||
if err == nil {
|
||||
if records, err := netutils.ResolveNS(ctx, direct.SymmetricDirect, systemDns, domain, false); err == nil && len(records) > 0 {
|
||||
// Has NX records. It is a real domain.
|
||||
dialMode = consts.DialMode_Domain
|
||||
// Check if the domain is in real domain set (bloom filter).
|
||||
c.muRealDomainSet.RLock()
|
||||
if c.realDomainSet.TestString(domain) {
|
||||
c.muRealDomainSet.RUnlock()
|
||||
dialMode = consts.DialMode_Domain
|
||||
} else {
|
||||
c.muRealDomainSet.RUnlock()
|
||||
// Lookup A/AAAA to make sure it is a real domain.
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), 5*time.Second)
|
||||
defer cancel()
|
||||
systemDns, err := netutils.SystemDns()
|
||||
if err == nil {
|
||||
if ip46, err := netutils.ResolveIp46(ctx, direct.SymmetricDirect, systemDns, domain, false, true); err == nil && (ip46.Ip4.IsValid() || ip46.Ip6.IsValid()) {
|
||||
// Has NS records. It is a real domain.
|
||||
dialMode = consts.DialMode_Domain
|
||||
// Add it to real domain set.
|
||||
c.muRealDomainSet.Lock()
|
||||
c.realDomainSet.AddString(domain)
|
||||
c.muRealDomainSet.Unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
2
go.mod
2
go.mod
@ -5,6 +5,7 @@ go 1.18
|
||||
require (
|
||||
github.com/adrg/xdg v0.4.0
|
||||
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20221202181307-76fa05c21b12
|
||||
github.com/bits-and-blooms/bloom/v3 v3.3.1
|
||||
github.com/cilium/ebpf v0.10.0
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/json-iterator/go v1.1.12
|
||||
@ -26,6 +27,7 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bits-and-blooms/bitset v1.3.1 // indirect
|
||||
github.com/dgryski/go-camellia v0.0.0-20191119043421-69a8a13fb23d // indirect
|
||||
github.com/dgryski/go-idea v0.0.0-20170306091226-d2fb45a411fb // indirect
|
||||
github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165 // indirect
|
||||
|
6
go.sum
6
go.sum
@ -2,6 +2,10 @@ github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
|
||||
github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E=
|
||||
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20221202181307-76fa05c21b12 h1:npHgfD4Tl2WJS3AJaMUi5ynGDPUBfkg3U3fCzDyXZ+4=
|
||||
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20221202181307-76fa05c21b12/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM=
|
||||
github.com/bits-and-blooms/bitset v1.3.1 h1:y+qrlmq3XsWi+xZqSaueaE8ry8Y127iMxlMfqcK8p0g=
|
||||
github.com/bits-and-blooms/bitset v1.3.1/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||
github.com/bits-and-blooms/bloom/v3 v3.3.1 h1:K2+A19bXT8gJR5mU7y+1yW6hsKfNCjcP2uNfLFKncjQ=
|
||||
github.com/bits-and-blooms/bloom/v3 v3.3.1/go.mod h1:bhUUknWd5khVbTe4UgMCSiOOVJzr3tMoijSK3WwvW90=
|
||||
github.com/cilium/ebpf v0.10.0 h1:nk5HPMeoBXtOzbkZBWym+ZWq1GIiHUsBFXxwewXAHLQ=
|
||||
github.com/cilium/ebpf v0.10.0/go.mod h1:DPiVdY/kT534dgc9ERmvP8mWA+9gvwgKfRvk4nNWnoE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
@ -107,6 +111,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg=
|
||||
github.com/twmb/murmur3 v1.1.6/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ=
|
||||
github.com/v2rayA/ahocorasick-domain v0.0.0-20230218160829-122a074c48c8 h1:2Liq3JvM/acVQZ7Gq9U5PpznMzlFRPYMPQxC2yXSi74=
|
||||
github.com/v2rayA/ahocorasick-domain v0.0.0-20230218160829-122a074c48c8/go.mod h1:mWch8I826zic/bKaCyE9ZZbWtFgEW0ox3EQ0NGm5DGw=
|
||||
github.com/v2rayA/dae-config-dist/go/dae_config v0.0.0-20230219173344-413f12027632 h1:MJ6+M3MpiVMdiZn3An88ZFNeLcLiN7hTaPsd2bVyduI=
|
||||
|
Loading…
Reference in New Issue
Block a user