Skip to content

Commit

Permalink
reset resolver's connection after default interface changed
Browse files Browse the repository at this point in the history
  • Loading branch information
wwqgtxx committed Sep 27, 2024
1 parent 1200810 commit 380d473
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 25 deletions.
2 changes: 1 addition & 1 deletion adapter/outbound/wireguard.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ func NewWireGuard(option WireGuardOption) (*WireGuard, error) {
for i := range nss {
nss[i].ProxyAdapter = refP
}
outbound.resolver = dns.NewResolver(dns.Config{
outbound.resolver, _ = dns.NewResolver(dns.Config{
Main: nss,
IPv6: has6,
})
Expand Down
10 changes: 10 additions & 0 deletions component/resolver/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type Resolver interface {
ExchangeContext(ctx context.Context, m *dns.Msg) (msg *dns.Msg, err error)
Invalid() bool
ClearCache()
ResetConnection()
}

// LookupIPv4WithResolver same as LookupIPv4, but with a resolver
Expand Down Expand Up @@ -250,6 +251,15 @@ func LookupIPProxyServerHost(ctx context.Context, host string) ([]netip.Addr, er
return LookupIP(ctx, host)
}

func ResetConnection() {
if DefaultResolver != nil {
go DefaultResolver.ResetConnection()
}
if ProxyServerHostResolver != nil {
go ProxyServerHostResolver.ResetConnection()
}
}

func SortationAddr(ips []netip.Addr) (ipv4s, ipv6s []netip.Addr) {
for _, v := range ips {
if v.Unmap().Is4() {
Expand Down
2 changes: 2 additions & 0 deletions dns/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,5 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error)
return ret.msg, ret.err
}
}

func (c *client) ResetConnection() {}
6 changes: 6 additions & 0 deletions dns/dhcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ func (d *dhcpClient) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg,
return
}

func (d *dhcpClient) ResetConnection() {
for _, client := range d.clients {
client.ResetConnection()
}
}

func (d *dhcpClient) resolve(ctx context.Context) ([]dnsClient, error) {
d.lock.Lock()

Expand Down
4 changes: 4 additions & 0 deletions dns/doh.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ func (doh *dohClient) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg
return
}

func (doh *dohClient) ResetConnection() {
doh.transport.CloseIdleConnections()
}

// newRequest returns a new DoH request given a dns.Msg.
func (doh *dohClient) newRequest(m *D.Msg) (*http.Request, error) {
buf, err := m.Pack()
Expand Down
2 changes: 2 additions & 0 deletions dns/rcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,5 @@ func (r rcodeClient) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, err
func (r rcodeClient) Address() string {
return r.addr
}

func (r rcodeClient) ResetConnection() {}
60 changes: 38 additions & 22 deletions dns/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"strings"
"time"

"github.com/metacubex/mihomo/common/cache"
lru "github.com/metacubex/mihomo/common/cache"
"github.com/metacubex/mihomo/common/singleflight"
"github.com/metacubex/mihomo/component/fakeip"
"github.com/metacubex/mihomo/component/resolver"
Expand All @@ -25,6 +25,7 @@ import (
type dnsClient interface {
ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, err error)
Address() string
ResetConnection()
}

type result struct {
Expand All @@ -40,10 +41,10 @@ type Resolver struct {
fallbackDomainFilters []C.DomainMatcher
fallbackIPFilters []C.IpMatcher
group singleflight.Group[*D.Msg]
lruCache *cache.LruCache[string, *D.Msg]
lruCache *lru.LruCache[string, *D.Msg]
policy []dnsPolicy
searchDomains []string
proxyServer []dnsClient
defaultResolver *Resolver
}

// LookupIPPrimaryIPv4 request with TypeA and TypeAAAA, priority return TypeA
Expand Down Expand Up @@ -399,6 +400,20 @@ func (r *Resolver) ClearCache() {
}
}

func (r *Resolver) ResetConnection() {
if r != nil {
for _, c := range r.main {
c.ResetConnection()
}
for _, c := range r.fallback {
c.ResetConnection()
}
if dr := r.defaultResolver; dr != nil {
dr.ResetConnection()
}
}
}

type NameServer struct {
Net string
Addr string
Expand All @@ -408,6 +423,10 @@ type NameServer struct {
Params map[string]string
}

func (config Config) newCache() *lru.LruCache[string, *D.Msg] {
return lru.New(lru.WithSize[string, *D.Msg](4096), lru.WithStale[string, *D.Msg](true))
}

func (ns NameServer) Equal(ns2 NameServer) bool {
defer func() {
// C.ProxyAdapter compare maybe panic, just ignore
Expand Down Expand Up @@ -446,10 +465,10 @@ type Config struct {
SearchDomains []string
}

func NewResolver(config Config) *Resolver {
func NewResolver(config Config) (r *Resolver, pr *Resolver) {
defaultResolver := &Resolver{
main: transform(config.Default, nil),
lruCache: cache.New[string, *D.Msg](cache.WithSize[string, *D.Msg](4096), cache.WithStale[string, *D.Msg](true)),
lruCache: config.newCache(),
}

var nameServerCache []struct {
Expand Down Expand Up @@ -479,20 +498,27 @@ func NewResolver(config Config) *Resolver {
return
}

r := &Resolver{
r = &Resolver{
ipv6: config.IPv6,
main: cacheTransform(config.Main),
lruCache: cache.New[string, *D.Msg](cache.WithSize[string, *D.Msg](4096), cache.WithStale[string, *D.Msg](true)),
lruCache: config.newCache(),
hosts: config.Hosts,
searchDomains: config.SearchDomains,
}
r.defaultResolver = defaultResolver

if len(config.Fallback) != 0 {
r.fallback = cacheTransform(config.Fallback)
if len(config.ProxyServer) != 0 {
pr = &Resolver{
ipv6: config.IPv6,
main: cacheTransform(config.ProxyServer),
lruCache: config.newCache(),
hosts: config.Hosts,
searchDomains: config.SearchDomains,
}
}

if len(config.ProxyServer) != 0 {
r.proxyServer = cacheTransform(config.ProxyServer)
if len(config.Fallback) != 0 {
r.fallback = cacheTransform(config.Fallback)
}

if len(config.Policy) != 0 {
Expand Down Expand Up @@ -525,17 +551,7 @@ func NewResolver(config Config) *Resolver {
r.fallbackIPFilters = config.FallbackIPFilter
r.fallbackDomainFilters = config.FallbackDomainFilter

return r
}

func NewProxyServerHostResolver(old *Resolver) *Resolver {
r := &Resolver{
ipv6: old.ipv6,
main: old.proxyServer,
lruCache: old.lruCache,
hosts: old.hosts,
}
return r
return
}

var ParseNameServer func(servers []string) ([]NameServer, error) // define in config/config.go
2 changes: 2 additions & 0 deletions dns/system_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,5 @@ func (c *systemClient) getDnsClients() ([]dnsClient, error) {
}
return nil, err
}

func (c *systemClient) ResetConnection() {}
4 changes: 2 additions & 2 deletions hub/executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ func ApplyConfig(cfg *config.Config, force bool) {
loadProvider(cfg.RuleProviders)
updateTunnels(cfg.Tunnels)

resolver.ResetConnection()
runtime.GC()
}

Expand Down Expand Up @@ -227,8 +228,7 @@ func updateDNS(c *config.DNS, ruleProvider map[string]providerTypes.RuleProvider
SearchDomains: c.SearchDomains,
}

r := dns.NewResolver(cfg)
pr := dns.NewProxyServerHostResolver(r)
r, pr := dns.NewResolver(cfg)
m := dns.NewEnhancer(cfg)

// reuse cache of old host mapper
Expand Down
5 changes: 5 additions & 0 deletions listener/sing_tun/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,10 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis

//l.openAndroidHotspot(tunOptions)

if !l.options.AutoDetectInterface {
resolver.ResetConnection()
}

if options.FileDescriptor != 0 {
tunName = fmt.Sprintf("%s(fd=%d)", tunName, options.FileDescriptor)
}
Expand Down Expand Up @@ -507,6 +511,7 @@ func (l *Listener) FlushDefaultInterface() {
if old := dialer.DefaultInterface.Swap(autoDetectInterfaceName); old != autoDetectInterfaceName {
log.Warnln("[TUN] default interface changed by monitor, %s => %s", old, autoDetectInterfaceName)
iface.FlushCache()
resolver.ResetConnection() // reset resolver's connection after default interface changed
}
return
}
Expand Down

0 comments on commit 380d473

Please sign in to comment.