mirror of
https://github.com/bolucat/Archive.git
synced 2025-12-24 13:28:37 +08:00
Update On Mon Sep 29 20:38:49 CEST 2025
This commit is contained in:
@@ -6,15 +6,15 @@ import (
|
||||
D "github.com/miekg/dns"
|
||||
)
|
||||
|
||||
var DefaultLocalServer LocalServer
|
||||
var DefaultService Service
|
||||
|
||||
type LocalServer interface {
|
||||
type Service interface {
|
||||
ServeMsg(ctx context.Context, msg *D.Msg) (*D.Msg, error)
|
||||
}
|
||||
|
||||
// ServeMsg with a dns.Msg, return resolve dns.Msg
|
||||
func ServeMsg(ctx context.Context, msg *D.Msg) (*D.Msg, error) {
|
||||
if server := DefaultLocalServer; server != nil {
|
||||
if server := DefaultService; server != nil {
|
||||
return server.ServeMsg(ctx, msg)
|
||||
}
|
||||
|
||||
@@ -146,6 +146,7 @@ type DNS struct {
|
||||
PreferH3 bool
|
||||
IPv6 bool
|
||||
IPv6Timeout uint
|
||||
UseHosts bool
|
||||
UseSystemHosts bool
|
||||
NameServer []dns.NameServer
|
||||
Fallback []dns.NameServer
|
||||
@@ -157,7 +158,6 @@ type DNS struct {
|
||||
CacheAlgorithm string
|
||||
CacheMaxSize int
|
||||
FakeIPRange *fakeip.Pool
|
||||
Hosts *trie.DomainTrie[resolver.HostValue]
|
||||
NameServerPolicy []dns.Policy
|
||||
ProxyServerNameserver []dns.NameServer
|
||||
DirectNameServer []dns.NameServer
|
||||
@@ -680,7 +680,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
|
||||
}
|
||||
config.Hosts = hosts
|
||||
|
||||
dnsCfg, err := parseDNS(rawCfg, hosts, ruleProviders)
|
||||
dnsCfg, err := parseDNS(rawCfg, ruleProviders)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1341,7 +1341,7 @@ func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], rulePro
|
||||
return policy, nil
|
||||
}
|
||||
|
||||
func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], ruleProviders map[string]providerTypes.RuleProvider) (*DNS, error) {
|
||||
func parseDNS(rawCfg *RawConfig, ruleProviders map[string]providerTypes.RuleProvider) (*DNS, error) {
|
||||
cfg := rawCfg.DNS
|
||||
if cfg.Enable && len(cfg.NameServer) == 0 {
|
||||
return nil, fmt.Errorf("if DNS configuration is turned on, NameServer cannot be empty")
|
||||
@@ -1357,6 +1357,7 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
|
||||
PreferH3: cfg.PreferH3,
|
||||
IPv6Timeout: cfg.IPv6Timeout,
|
||||
IPv6: cfg.IPv6,
|
||||
UseHosts: cfg.UseHosts,
|
||||
UseSystemHosts: cfg.UseSystemHosts,
|
||||
EnhancedMode: cfg.EnhancedMode,
|
||||
CacheAlgorithm: cfg.CacheAlgorithm,
|
||||
@@ -1490,10 +1491,6 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.UseHosts {
|
||||
dnsCfg.Hosts = hosts
|
||||
}
|
||||
|
||||
return dnsCfg, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@ package context
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/metacubex/mihomo/common/utils"
|
||||
|
||||
"github.com/gofrs/uuid/v5"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -17,17 +17,15 @@ const (
|
||||
type DNSContext struct {
|
||||
context.Context
|
||||
|
||||
id uuid.UUID
|
||||
msg *dns.Msg
|
||||
tp string
|
||||
id uuid.UUID
|
||||
tp string
|
||||
}
|
||||
|
||||
func NewDNSContext(ctx context.Context, msg *dns.Msg) *DNSContext {
|
||||
func NewDNSContext(ctx context.Context) *DNSContext {
|
||||
return &DNSContext{
|
||||
Context: ctx,
|
||||
|
||||
id: utils.NewUUIDV4(),
|
||||
msg: msg,
|
||||
id: utils.NewUUIDV4(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ type ResolverEnhancer struct {
|
||||
mode C.DNSMode
|
||||
fakePool *fakeip.Pool
|
||||
mapping *lru.LruCache[netip.Addr, string]
|
||||
useHosts bool
|
||||
}
|
||||
|
||||
func (h *ResolverEnhancer) FakeIPEnabled() bool {
|
||||
@@ -103,7 +104,13 @@ func (h *ResolverEnhancer) StoreFakePoolState() {
|
||||
}
|
||||
}
|
||||
|
||||
func NewEnhancer(cfg Config) *ResolverEnhancer {
|
||||
type EnhancerConfig struct {
|
||||
EnhancedMode C.DNSMode
|
||||
Pool *fakeip.Pool
|
||||
UseHosts bool
|
||||
}
|
||||
|
||||
func NewEnhancer(cfg EnhancerConfig) *ResolverEnhancer {
|
||||
var fakePool *fakeip.Pool
|
||||
var mapping *lru.LruCache[netip.Addr, string]
|
||||
|
||||
@@ -116,5 +123,6 @@ func NewEnhancer(cfg Config) *ResolverEnhancer {
|
||||
mode: cfg.EnhancedMode,
|
||||
fakePool: fakePool,
|
||||
mapping: mapping,
|
||||
useHosts: cfg.UseHosts,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
D "github.com/miekg/dns"
|
||||
)
|
||||
|
||||
type LocalServer struct {
|
||||
handler handler
|
||||
}
|
||||
|
||||
// ServeMsg implement resolver.LocalServer ResolveMsg
|
||||
func (s *LocalServer) ServeMsg(ctx context.Context, msg *D.Msg) (*D.Msg, error) {
|
||||
return handlerWithContext(ctx, s.handler, msg)
|
||||
}
|
||||
|
||||
func NewLocalServer(resolver *Resolver, mapper *ResolverEnhancer) *LocalServer {
|
||||
return &LocalServer{handler: NewHandler(resolver, mapper)}
|
||||
}
|
||||
@@ -7,22 +7,22 @@ import (
|
||||
|
||||
"github.com/metacubex/mihomo/common/lru"
|
||||
"github.com/metacubex/mihomo/component/fakeip"
|
||||
R "github.com/metacubex/mihomo/component/resolver"
|
||||
"github.com/metacubex/mihomo/component/resolver"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/context"
|
||||
icontext "github.com/metacubex/mihomo/context"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
|
||||
D "github.com/miekg/dns"
|
||||
)
|
||||
|
||||
type (
|
||||
handler func(ctx *context.DNSContext, r *D.Msg) (*D.Msg, error)
|
||||
handler func(ctx *icontext.DNSContext, r *D.Msg) (*D.Msg, error)
|
||||
middleware func(next handler) handler
|
||||
)
|
||||
|
||||
func withHosts(hosts R.Hosts, mapping *lru.LruCache[netip.Addr, string]) middleware {
|
||||
func withHosts(mapping *lru.LruCache[netip.Addr, string]) middleware {
|
||||
return func(next handler) handler {
|
||||
return func(ctx *context.DNSContext, r *D.Msg) (*D.Msg, error) {
|
||||
return func(ctx *icontext.DNSContext, r *D.Msg) (*D.Msg, error) {
|
||||
q := r.Question[0]
|
||||
|
||||
if !isIPRequest(q) {
|
||||
@@ -36,7 +36,7 @@ func withHosts(hosts R.Hosts, mapping *lru.LruCache[netip.Addr, string]) middlew
|
||||
rr.Target = domain + "."
|
||||
resp.Answer = append([]D.RR{rr}, resp.Answer...)
|
||||
}
|
||||
record, ok := hosts.Search(host, q.Qtype != D.TypeA && q.Qtype != D.TypeAAAA)
|
||||
record, ok := resolver.DefaultHosts.Search(host, q.Qtype != D.TypeA && q.Qtype != D.TypeAAAA)
|
||||
if !ok {
|
||||
if record != nil && record.IsDomain {
|
||||
// replace request domain
|
||||
@@ -88,7 +88,7 @@ func withHosts(hosts R.Hosts, mapping *lru.LruCache[netip.Addr, string]) middlew
|
||||
return next(ctx, r)
|
||||
}
|
||||
|
||||
ctx.SetType(context.DNSTypeHost)
|
||||
ctx.SetType(icontext.DNSTypeHost)
|
||||
msg.SetRcode(r, D.RcodeSuccess)
|
||||
msg.Authoritative = true
|
||||
msg.RecursionAvailable = true
|
||||
@@ -99,7 +99,7 @@ func withHosts(hosts R.Hosts, mapping *lru.LruCache[netip.Addr, string]) middlew
|
||||
|
||||
func withMapping(mapping *lru.LruCache[netip.Addr, string]) middleware {
|
||||
return func(next handler) handler {
|
||||
return func(ctx *context.DNSContext, r *D.Msg) (*D.Msg, error) {
|
||||
return func(ctx *icontext.DNSContext, r *D.Msg) (*D.Msg, error) {
|
||||
q := r.Question[0]
|
||||
|
||||
if !isIPRequest(q) {
|
||||
@@ -149,7 +149,7 @@ func withMapping(mapping *lru.LruCache[netip.Addr, string]) middleware {
|
||||
|
||||
func withFakeIP(fakePool *fakeip.Pool) middleware {
|
||||
return func(next handler) handler {
|
||||
return func(ctx *context.DNSContext, r *D.Msg) (*D.Msg, error) {
|
||||
return func(ctx *icontext.DNSContext, r *D.Msg) (*D.Msg, error) {
|
||||
q := r.Question[0]
|
||||
|
||||
host := strings.TrimRight(q.Name, ".")
|
||||
@@ -173,7 +173,7 @@ func withFakeIP(fakePool *fakeip.Pool) middleware {
|
||||
msg := r.Copy()
|
||||
msg.Answer = []D.RR{rr}
|
||||
|
||||
ctx.SetType(context.DNSTypeFakeIP)
|
||||
ctx.SetType(icontext.DNSTypeFakeIP)
|
||||
setMsgTTL(msg, 1)
|
||||
msg.SetRcode(r, D.RcodeSuccess)
|
||||
msg.Authoritative = true
|
||||
@@ -185,8 +185,8 @@ func withFakeIP(fakePool *fakeip.Pool) middleware {
|
||||
}
|
||||
|
||||
func withResolver(resolver *Resolver) handler {
|
||||
return func(ctx *context.DNSContext, r *D.Msg) (*D.Msg, error) {
|
||||
ctx.SetType(context.DNSTypeRaw)
|
||||
return func(ctx *icontext.DNSContext, r *D.Msg) (*D.Msg, error) {
|
||||
ctx.SetType(icontext.DNSTypeRaw)
|
||||
|
||||
q := r.Question[0]
|
||||
|
||||
@@ -218,11 +218,11 @@ func compose(middlewares []middleware, endpoint handler) handler {
|
||||
return h
|
||||
}
|
||||
|
||||
func NewHandler(resolver *Resolver, mapper *ResolverEnhancer) handler {
|
||||
middlewares := []middleware{}
|
||||
func newHandler(resolver *Resolver, mapper *ResolverEnhancer) handler {
|
||||
var middlewares []middleware
|
||||
|
||||
if resolver.hosts != nil {
|
||||
middlewares = append(middlewares, withHosts(R.NewHosts(resolver.hosts), mapper.mapping))
|
||||
if mapper.useHosts {
|
||||
middlewares = append(middlewares, withHosts(mapper.mapping))
|
||||
}
|
||||
|
||||
if mapper.mode == C.DNSFakeIP {
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"github.com/metacubex/mihomo/common/arc"
|
||||
"github.com/metacubex/mihomo/common/lru"
|
||||
"github.com/metacubex/mihomo/common/singleflight"
|
||||
"github.com/metacubex/mihomo/component/fakeip"
|
||||
"github.com/metacubex/mihomo/component/resolver"
|
||||
"github.com/metacubex/mihomo/component/trie"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
@@ -40,7 +39,6 @@ type result struct {
|
||||
type Resolver struct {
|
||||
ipv6 bool
|
||||
ipv6Timeout time.Duration
|
||||
hosts *trie.DomainTrie[resolver.HostValue]
|
||||
main []dnsClient
|
||||
fallback []dnsClient
|
||||
fallbackDomainFilters []C.DomainMatcher
|
||||
@@ -452,11 +450,8 @@ type Config struct {
|
||||
DirectFollowPolicy bool
|
||||
IPv6 bool
|
||||
IPv6Timeout uint
|
||||
EnhancedMode C.DNSMode
|
||||
FallbackIPFilter []C.IpMatcher
|
||||
FallbackDomainFilter []C.DomainMatcher
|
||||
Pool *fakeip.Pool
|
||||
Hosts *trie.DomainTrie[resolver.HostValue]
|
||||
Policy []Policy
|
||||
CacheAlgorithm string
|
||||
CacheMaxSize int
|
||||
@@ -530,7 +525,6 @@ func NewResolver(config Config) (rs Resolvers) {
|
||||
ipv6: config.IPv6,
|
||||
main: cacheTransform(config.Main),
|
||||
cache: config.newCache(),
|
||||
hosts: config.Hosts,
|
||||
ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond,
|
||||
}
|
||||
r.defaultResolver = defaultResolver
|
||||
@@ -541,7 +535,6 @@ func NewResolver(config Config) (rs Resolvers) {
|
||||
ipv6: config.IPv6,
|
||||
main: cacheTransform(config.ProxyServer),
|
||||
cache: config.newCache(),
|
||||
hosts: config.Hosts,
|
||||
ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond,
|
||||
}
|
||||
}
|
||||
@@ -551,7 +544,6 @@ func NewResolver(config Config) (rs Resolvers) {
|
||||
ipv6: config.IPv6,
|
||||
main: cacheTransform(config.DirectServer),
|
||||
cache: config.newCache(),
|
||||
hosts: config.Hosts,
|
||||
ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
stdContext "context"
|
||||
"errors"
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"github.com/metacubex/mihomo/adapter/inbound"
|
||||
"github.com/metacubex/mihomo/common/sockopt"
|
||||
"github.com/metacubex/mihomo/context"
|
||||
"github.com/metacubex/mihomo/component/resolver"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
|
||||
D "github.com/miekg/dns"
|
||||
@@ -21,39 +20,32 @@ var (
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
handler handler
|
||||
service resolver.Service
|
||||
tcpServer *D.Server
|
||||
udpServer *D.Server
|
||||
}
|
||||
|
||||
// ServeDNS implement D.Handler ServeDNS
|
||||
func (s *Server) ServeDNS(w D.ResponseWriter, r *D.Msg) {
|
||||
msg, err := handlerWithContext(stdContext.Background(), s.handler, r)
|
||||
msg, err := s.service.ServeMsg(context.Background(), r)
|
||||
if err != nil {
|
||||
D.HandleFailed(w, r)
|
||||
m := new(D.Msg)
|
||||
m.SetRcode(r, D.RcodeServerFailure)
|
||||
// does not matter if this write fails
|
||||
w.WriteMsg(m)
|
||||
return
|
||||
}
|
||||
msg.Compress = true
|
||||
w.WriteMsg(msg)
|
||||
}
|
||||
|
||||
func handlerWithContext(stdCtx stdContext.Context, handler handler, msg *D.Msg) (*D.Msg, error) {
|
||||
if len(msg.Question) == 0 {
|
||||
return nil, errors.New("at least one question is required")
|
||||
}
|
||||
|
||||
ctx := context.NewDNSContext(stdCtx, msg)
|
||||
return handler(ctx, msg)
|
||||
func (s *Server) SetService(service resolver.Service) {
|
||||
s.service = service
|
||||
}
|
||||
|
||||
func (s *Server) SetHandler(handler handler) {
|
||||
s.handler = handler
|
||||
}
|
||||
|
||||
func ReCreateServer(addr string, resolver *Resolver, mapper *ResolverEnhancer) {
|
||||
if addr == address && resolver != nil {
|
||||
handler := NewHandler(resolver, mapper)
|
||||
server.SetHandler(handler)
|
||||
func ReCreateServer(addr string, service resolver.Service) {
|
||||
if addr == address && service != nil {
|
||||
server.SetService(service)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -67,10 +59,10 @@ func ReCreateServer(addr string, resolver *Resolver, mapper *ResolverEnhancer) {
|
||||
server.udpServer = nil
|
||||
}
|
||||
|
||||
server.handler = nil
|
||||
server.service = nil
|
||||
address = ""
|
||||
|
||||
if addr == "" {
|
||||
if addr == "" || service == nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -87,8 +79,7 @@ func ReCreateServer(addr string, resolver *Resolver, mapper *ResolverEnhancer) {
|
||||
}
|
||||
|
||||
address = addr
|
||||
handler := NewHandler(resolver, mapper)
|
||||
server = &Server{handler: handler}
|
||||
server = &Server{service: service}
|
||||
|
||||
go func() {
|
||||
p, err := inbound.ListenPacket("udp", addr)
|
||||
|
||||
29
mihomo/dns/service.go
Normal file
29
mihomo/dns/service.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/metacubex/mihomo/component/resolver"
|
||||
icontext "github.com/metacubex/mihomo/context"
|
||||
D "github.com/miekg/dns"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
handler handler
|
||||
}
|
||||
|
||||
// ServeMsg implement [resolver.Service] ResolveMsg
|
||||
func (s *Service) ServeMsg(ctx context.Context, msg *D.Msg) (*D.Msg, error) {
|
||||
if len(msg.Question) == 0 {
|
||||
return nil, errors.New("at least one question is required")
|
||||
}
|
||||
|
||||
return s.handler(icontext.NewDNSContext(ctx), msg)
|
||||
}
|
||||
|
||||
var _ resolver.Service = (*Service)(nil)
|
||||
|
||||
func NewService(resolver *Resolver, mapper *ResolverEnhancer) *Service {
|
||||
return &Service{handler: newHandler(resolver, mapper)}
|
||||
}
|
||||
@@ -240,20 +240,18 @@ func updateDNS(c *config.DNS, generalIPv6 bool) {
|
||||
if !c.Enable {
|
||||
resolver.DefaultResolver = nil
|
||||
resolver.DefaultHostMapper = nil
|
||||
resolver.DefaultLocalServer = nil
|
||||
resolver.DefaultService = nil
|
||||
resolver.ProxyServerHostResolver = nil
|
||||
resolver.DirectHostResolver = nil
|
||||
dns.ReCreateServer("", nil, nil)
|
||||
dns.ReCreateServer("", nil)
|
||||
return
|
||||
}
|
||||
cfg := dns.Config{
|
||||
|
||||
r := dns.NewResolver(dns.Config{
|
||||
Main: c.NameServer,
|
||||
Fallback: c.Fallback,
|
||||
IPv6: c.IPv6 && generalIPv6,
|
||||
IPv6Timeout: c.IPv6Timeout,
|
||||
EnhancedMode: c.EnhancedMode,
|
||||
Pool: c.FakeIPRange,
|
||||
Hosts: c.Hosts,
|
||||
FallbackIPFilter: c.FallbackIPFilter,
|
||||
FallbackDomainFilter: c.FallbackDomainFilter,
|
||||
Default: c.DefaultNameserver,
|
||||
@@ -263,19 +261,23 @@ func updateDNS(c *config.DNS, generalIPv6 bool) {
|
||||
DirectFollowPolicy: c.DirectFollowPolicy,
|
||||
CacheAlgorithm: c.CacheAlgorithm,
|
||||
CacheMaxSize: c.CacheMaxSize,
|
||||
}
|
||||
|
||||
r := dns.NewResolver(cfg)
|
||||
m := dns.NewEnhancer(cfg)
|
||||
})
|
||||
m := dns.NewEnhancer(dns.EnhancerConfig{
|
||||
EnhancedMode: c.EnhancedMode,
|
||||
Pool: c.FakeIPRange,
|
||||
UseHosts: c.UseHosts,
|
||||
})
|
||||
|
||||
// reuse cache of old host mapper
|
||||
if old := resolver.DefaultHostMapper; old != nil {
|
||||
m.PatchFrom(old.(*dns.ResolverEnhancer))
|
||||
}
|
||||
|
||||
s := dns.NewService(r.Resolver, m)
|
||||
|
||||
resolver.DefaultResolver = r
|
||||
resolver.DefaultHostMapper = m
|
||||
resolver.DefaultLocalServer = dns.NewLocalServer(r.Resolver, m)
|
||||
resolver.DefaultService = s
|
||||
resolver.UseSystemHosts = c.UseSystemHosts
|
||||
|
||||
if r.ProxyResolver.Invalid() {
|
||||
@@ -290,7 +292,7 @@ func updateDNS(c *config.DNS, generalIPv6 bool) {
|
||||
resolver.DirectHostResolver = r.Resolver
|
||||
}
|
||||
|
||||
dns.ReCreateServer(c.Listen, r.Resolver, m)
|
||||
dns.ReCreateServer(c.Listen, s)
|
||||
}
|
||||
|
||||
func updateHosts(tree *trie.DomainTrie[resolver.HostValue]) {
|
||||
|
||||
Reference in New Issue
Block a user