mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-19 16:30:07 +08:00
feat: all dns client support disable-ipv4 and disable-ipv6 params
This commit is contained in:
parent
2f9a3b3469
commit
29a37f4f4b
@ -1168,10 +1168,21 @@ func parseNameServer(servers []string, respectRules bool, preferH3 bool) ([]dns.
|
||||
return nil, fmt.Errorf("DNS NameServer[%d] format error: %s", idx, err.Error())
|
||||
}
|
||||
|
||||
proxyName := u.Fragment
|
||||
var proxyName string
|
||||
params := map[string]string{}
|
||||
for _, s := range strings.Split(u.Fragment, "&") {
|
||||
arr := strings.SplitN(s, "=", 2)
|
||||
switch len(arr) {
|
||||
case 0:
|
||||
continue
|
||||
case 1:
|
||||
proxyName = arr[0]
|
||||
case 2:
|
||||
params[arr[0]] = arr[1]
|
||||
}
|
||||
}
|
||||
|
||||
var addr, dnsNetType string
|
||||
params := map[string]string{}
|
||||
switch u.Scheme {
|
||||
case "udp":
|
||||
addr, err = hostWithDefaultPort(u.Host, "53")
|
||||
@ -1189,23 +1200,8 @@ func parseNameServer(servers []string, respectRules bool, preferH3 bool) ([]dns.
|
||||
addr, err = hostWithDefaultPort(u.Host, "80")
|
||||
}
|
||||
if err == nil {
|
||||
proxyName = ""
|
||||
clearURL := url.URL{Scheme: u.Scheme, Host: addr, Path: u.Path, User: u.User}
|
||||
addr = clearURL.String()
|
||||
if len(u.Fragment) != 0 {
|
||||
for _, s := range strings.Split(u.Fragment, "&") {
|
||||
arr := strings.Split(s, "=")
|
||||
if len(arr) == 0 {
|
||||
continue
|
||||
} else if len(arr) == 1 {
|
||||
proxyName = arr[0]
|
||||
} else if len(arr) == 2 {
|
||||
params[arr[0]] = arr[1]
|
||||
} else {
|
||||
params[arr[0]] = strings.Join(arr[1:], "=")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case "quic":
|
||||
addr, err = hostWithDefaultPort(u.Host, "853")
|
||||
|
||||
@ -6,8 +6,10 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/component/ca"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
|
||||
D "github.com/miekg/dns"
|
||||
@ -105,3 +107,20 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error)
|
||||
}
|
||||
|
||||
func (c *client) ResetConnection() {}
|
||||
|
||||
func newClient(addr string, resolver *Resolver, netType string, proxyAdapter C.ProxyAdapter, proxyName string) *client {
|
||||
host, port, _ := net.SplitHostPort(addr)
|
||||
return &client{
|
||||
Client: &D.Client{
|
||||
Net: netType,
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: host,
|
||||
},
|
||||
UDPSize: 4096,
|
||||
Timeout: 5 * time.Second,
|
||||
},
|
||||
port: port,
|
||||
host: host,
|
||||
dialer: newDNSDialer(resolver, proxyAdapter, proxyName),
|
||||
}
|
||||
}
|
||||
|
||||
62
dns/util.go
62
dns/util.go
@ -2,10 +2,8 @@ package dns
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strings"
|
||||
"time"
|
||||
@ -92,42 +90,54 @@ func isIPRequest(q D.Question) bool {
|
||||
func transform(servers []NameServer, resolver *Resolver) []dnsClient {
|
||||
ret := make([]dnsClient, 0, len(servers))
|
||||
for _, s := range servers {
|
||||
var c dnsClient
|
||||
switch s.Net {
|
||||
case "https":
|
||||
ret = append(ret, newDoHClient(s.Addr, resolver, s.PreferH3, s.Params, s.ProxyAdapter, s.ProxyName))
|
||||
continue
|
||||
c = newDoHClient(s.Addr, resolver, s.PreferH3, s.Params, s.ProxyAdapter, s.ProxyName)
|
||||
case "dhcp":
|
||||
ret = append(ret, newDHCPClient(s.Addr))
|
||||
continue
|
||||
c = newDHCPClient(s.Addr)
|
||||
case "system":
|
||||
ret = append(ret, newSystemClient())
|
||||
continue
|
||||
c = newSystemClient()
|
||||
case "rcode":
|
||||
ret = append(ret, newRCodeClient(s.Addr))
|
||||
continue
|
||||
c = newRCodeClient(s.Addr)
|
||||
case "quic":
|
||||
ret = append(ret, newDoQ(s.Addr, resolver, s.ProxyAdapter, s.ProxyName))
|
||||
continue
|
||||
c = newDoQ(s.Addr, resolver, s.ProxyAdapter, s.ProxyName)
|
||||
default:
|
||||
c = newClient(s.Addr, resolver, s.Net, s.ProxyAdapter, s.ProxyName)
|
||||
}
|
||||
|
||||
host, port, _ := net.SplitHostPort(s.Addr)
|
||||
ret = append(ret, &client{
|
||||
Client: &D.Client{
|
||||
Net: s.Net,
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: host,
|
||||
},
|
||||
UDPSize: 4096,
|
||||
Timeout: 5 * time.Second,
|
||||
},
|
||||
port: port,
|
||||
host: host,
|
||||
dialer: newDNSDialer(resolver, s.ProxyAdapter, s.ProxyName),
|
||||
})
|
||||
if s.Params["disable-ipv4"] == "true" {
|
||||
c = newDisableTypeClient(c, D.TypeA)
|
||||
}
|
||||
|
||||
if s.Params["disable-ipv6"] == "true" {
|
||||
c = newDisableTypeClient(c, D.TypeAAAA)
|
||||
}
|
||||
|
||||
ret = append(ret, c)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type disableTypeClient struct {
|
||||
dnsClient
|
||||
qType uint16
|
||||
}
|
||||
|
||||
func (c disableTypeClient) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, err error) {
|
||||
if len(m.Question) > 0 {
|
||||
q := m.Question[0]
|
||||
if q.Qtype == c.qType {
|
||||
return handleMsgWithEmptyAnswer(m), nil
|
||||
}
|
||||
}
|
||||
return c.dnsClient.ExchangeContext(ctx, m)
|
||||
}
|
||||
|
||||
func newDisableTypeClient(c dnsClient, qType uint16) dnsClient {
|
||||
return disableTypeClient{c, qType}
|
||||
}
|
||||
|
||||
func handleMsgWithEmptyAnswer(r *D.Msg) *D.Msg {
|
||||
msg := &D.Msg{}
|
||||
msg.Answer = []D.RR{}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user