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())
|
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
|
var addr, dnsNetType string
|
||||||
params := map[string]string{}
|
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "udp":
|
case "udp":
|
||||||
addr, err = hostWithDefaultPort(u.Host, "53")
|
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")
|
addr, err = hostWithDefaultPort(u.Host, "80")
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
proxyName = ""
|
|
||||||
clearURL := url.URL{Scheme: u.Scheme, Host: addr, Path: u.Path, User: u.User}
|
clearURL := url.URL{Scheme: u.Scheme, Host: addr, Path: u.Path, User: u.User}
|
||||||
addr = clearURL.String()
|
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":
|
case "quic":
|
||||||
addr, err = hostWithDefaultPort(u.Host, "853")
|
addr, err = hostWithDefaultPort(u.Host, "853")
|
||||||
|
|||||||
@ -6,8 +6,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/metacubex/mihomo/component/ca"
|
"github.com/metacubex/mihomo/component/ca"
|
||||||
|
C "github.com/metacubex/mihomo/constant"
|
||||||
"github.com/metacubex/mihomo/log"
|
"github.com/metacubex/mihomo/log"
|
||||||
|
|
||||||
D "github.com/miekg/dns"
|
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 (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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -92,42 +90,54 @@ func isIPRequest(q D.Question) bool {
|
|||||||
func transform(servers []NameServer, resolver *Resolver) []dnsClient {
|
func transform(servers []NameServer, resolver *Resolver) []dnsClient {
|
||||||
ret := make([]dnsClient, 0, len(servers))
|
ret := make([]dnsClient, 0, len(servers))
|
||||||
for _, s := range servers {
|
for _, s := range servers {
|
||||||
|
var c dnsClient
|
||||||
switch s.Net {
|
switch s.Net {
|
||||||
case "https":
|
case "https":
|
||||||
ret = append(ret, newDoHClient(s.Addr, resolver, s.PreferH3, s.Params, s.ProxyAdapter, s.ProxyName))
|
c = newDoHClient(s.Addr, resolver, s.PreferH3, s.Params, s.ProxyAdapter, s.ProxyName)
|
||||||
continue
|
|
||||||
case "dhcp":
|
case "dhcp":
|
||||||
ret = append(ret, newDHCPClient(s.Addr))
|
c = newDHCPClient(s.Addr)
|
||||||
continue
|
|
||||||
case "system":
|
case "system":
|
||||||
ret = append(ret, newSystemClient())
|
c = newSystemClient()
|
||||||
continue
|
|
||||||
case "rcode":
|
case "rcode":
|
||||||
ret = append(ret, newRCodeClient(s.Addr))
|
c = newRCodeClient(s.Addr)
|
||||||
continue
|
|
||||||
case "quic":
|
case "quic":
|
||||||
ret = append(ret, newDoQ(s.Addr, resolver, s.ProxyAdapter, s.ProxyName))
|
c = newDoQ(s.Addr, resolver, s.ProxyAdapter, s.ProxyName)
|
||||||
continue
|
default:
|
||||||
|
c = newClient(s.Addr, resolver, s.Net, s.ProxyAdapter, s.ProxyName)
|
||||||
}
|
}
|
||||||
|
|
||||||
host, port, _ := net.SplitHostPort(s.Addr)
|
if s.Params["disable-ipv4"] == "true" {
|
||||||
ret = append(ret, &client{
|
c = newDisableTypeClient(c, D.TypeA)
|
||||||
Client: &D.Client{
|
}
|
||||||
Net: s.Net,
|
|
||||||
TLSConfig: &tls.Config{
|
if s.Params["disable-ipv6"] == "true" {
|
||||||
ServerName: host,
|
c = newDisableTypeClient(c, D.TypeAAAA)
|
||||||
},
|
}
|
||||||
UDPSize: 4096,
|
|
||||||
Timeout: 5 * time.Second,
|
ret = append(ret, c)
|
||||||
},
|
|
||||||
port: port,
|
|
||||||
host: host,
|
|
||||||
dialer: newDNSDialer(resolver, s.ProxyAdapter, s.ProxyName),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return ret
|
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 {
|
func handleMsgWithEmptyAnswer(r *D.Msg) *D.Msg {
|
||||||
msg := &D.Msg{}
|
msg := &D.Msg{}
|
||||||
msg.Answer = []D.RR{}
|
msg.Answer = []D.RR{}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user