Files
v2ray_simple/netLayer/dns_conf.go

177 lines
4.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package netLayer
import (
"net"
"net/netip"
"github.com/hahahrfool/v2ray_simple/utils"
"go.uber.org/zap"
)
type DnsConf struct {
Strategy int64 `toml:"strategy"` //0表示默认(和4含义相同), 4表示先查ip4后查ip6, 6表示先查6后查4; 40表示只查ipv4, 60 表示只查ipv6
Hosts map[string]any `toml:"hosts"` //用于强制指定哪些域名会被解析为哪些具体的ip可以为一个ip字符串或者一个 []string 数组, 数组内可以是A,AAAA或CNAME
Servers []any `toml:"servers"` //可以为一个地址url字符串或者为 SpecialDnsServerConf; 如果第一个元素是url字符串形式则此第一个元素将会被用作默认dns服务器
}
type SpecialDnsServerConf struct {
AddrUrlStr string `toml:"addr"` //必须为 udp://1.1.1.1:53 这种格式
Domains []string `toml:"domain"` //指定哪些域名需要通过 该dns服务器进行查询
}
func loadSpecialDnsServerConf_fromTomlUnmarshalledMap(m map[string]any) *SpecialDnsServerConf {
addr := m["addr"]
if addr == nil {
if ce := utils.CanLogErr("LoadDnsMachine, addr required"); ce != nil {
ce.Write()
}
return nil
}
addrStr, ok := addr.(string)
if !ok {
if ce := utils.CanLogErr("LoadDnsMachine, addr not a string"); ce != nil {
ce.Write()
}
return nil
}
domains := m["domain"]
if domains == nil {
if ce := utils.CanLogErr("LoadDnsMachine, domain required"); ce != nil {
ce.Write()
}
return nil
}
domainsAnySlice, ok := domains.([]any)
if !ok {
if ce := utils.CanLogErr("LoadDnsMachine, domain not a list"); ce != nil {
ce.Write()
}
return nil
}
domainsSlice := []string{}
for _, anyD := range domainsAnySlice {
dstr, ok := anyD.(string)
if !ok {
if ce := utils.CanLogErr("LoadDnsMachine, domain list contains non-string item"); ce != nil {
ce.Write()
}
return nil
}
domainsSlice = append(domainsSlice, dstr)
}
return &SpecialDnsServerConf{
Domains: domainsSlice,
AddrUrlStr: addrStr,
}
}
func LoadDnsMachine(conf *DnsConf) *DNSMachine {
var dm = &DNSMachine{TypeStrategy: conf.Strategy}
var ok = false
if len(conf.Servers) > 0 {
ok = true
servers := conf.Servers
dm.SpecialServerPollicy = make(map[string]string)
for _, ser := range servers {
switch server := ser.(type) {
case string:
ad, e := NewAddrByURL(server)
if e != nil {
if ce := utils.CanLogErr("LoadDnsMachine parse server url failed"); ce != nil {
ce.Write(zap.Error(e))
}
continue
}
dm.AddNewServer(server, &ad)
case map[string]any:
realServer := loadSpecialDnsServerConf_fromTomlUnmarshalledMap(server)
if realServer == nil {
continue
}
if len(realServer.Domains) <= 0 { //既然是特殊dns服务器, 那么就必须指定哪些域名要使用该dns服务器进行查询
if ce := utils.CanLogErr("LoadDnsMachine, special domain list required"); ce != nil {
ce.Write()
}
continue
}
addr, e := NewAddrByURL(realServer.AddrUrlStr)
if e != nil {
if ce := utils.CanLogErr("LoadDnsMachine, server url invalid"); ce != nil {
ce.Write(zap.Error(e))
}
continue
}
if err := dm.AddNewServer(realServer.AddrUrlStr, &addr); err != nil {
if ce := utils.CanLogErr("LoadDnsMachine, AddNewServer failed"); ce != nil {
ce.Write(zap.Error(err))
}
continue
}
for _, thisdomain := range realServer.Domains {
dm.SpecialServerPollicy[thisdomain] = realServer.AddrUrlStr
}
}
}
}
if conf.Hosts != nil {
ok = true
dm.SpecialIPPollicy = make(map[string][]netip.Addr)
for thishost, things := range conf.Hosts {
switch value := things.(type) {
case string:
ip := net.ParseIP(value)
ad, _ := netip.AddrFromSlice(ip)
dm.SpecialIPPollicy[thishost] = []netip.Addr{ad}
case []string:
for _, str := range value {
ad, err := NewAddrFromAny(str)
if err != nil {
if ce := utils.CanLogErr("LoadDnsMachine loading SpecialIP from list failed"); ce != nil {
ce.Write(zap.Error(err))
}
return nil
}
dm.SpecialIPPollicy[thishost] = append(dm.SpecialIPPollicy[thishost], ad.GetHashable().Addr())
}
}
}
}
if !ok {
return nil
}
return dm
}