mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-07-04 10:48:49 +00:00
359a28f876
https://github.com/XTLS/Xray-core/pull/6123#issuecomment-4439994266 https://github.com/XTLS/Xray-core/pull/6123#issuecomment-4441819696 https://github.com/XTLS/Xray-core/pull/6123#issuecomment-4522352460 Example: https://github.com/XTLS/Xray-core/pull/6123#issue-4436283689 Document: https://xtls.github.io/config/transports/finalmask.html#xdns
81 lines
1.4 KiB
Go
81 lines
1.4 KiB
Go
package xdns
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/xtls/xray-core/common/errors"
|
|
)
|
|
|
|
type domainSpec struct {
|
|
name Name
|
|
rrType uint16
|
|
}
|
|
|
|
func rrTypeFromMethod(method string) (uint16, error) {
|
|
switch strings.ToLower(method) {
|
|
case "", "txt":
|
|
return RRTypeTXT, nil
|
|
case "a":
|
|
return RRTypeA, nil
|
|
case "aaaa":
|
|
return RRTypeAAAA, nil
|
|
default:
|
|
return 0, errors.New("unsupported method")
|
|
}
|
|
}
|
|
|
|
func parseDomainSpec(s string, defaultMethod string) (domainSpec, error) {
|
|
domainPart := s
|
|
method := ""
|
|
hasMethod := false
|
|
|
|
if i := strings.LastIndex(s, ":"); i >= 0 {
|
|
domainPart = s[:i]
|
|
method = s[i+1:]
|
|
hasMethod = true
|
|
} else if defaultMethod != "" {
|
|
method = defaultMethod
|
|
hasMethod = true
|
|
}
|
|
|
|
if domainPart == "" {
|
|
return domainSpec{}, errors.New("empty domain")
|
|
}
|
|
|
|
name, err := ParseName(domainPart)
|
|
if err != nil {
|
|
return domainSpec{}, err
|
|
}
|
|
|
|
rrType := uint16(0)
|
|
if hasMethod {
|
|
var err error
|
|
rrType, err = rrTypeFromMethod(method)
|
|
if err != nil {
|
|
return domainSpec{}, err
|
|
}
|
|
}
|
|
|
|
return domainSpec{
|
|
name: name,
|
|
rrType: rrType,
|
|
}, nil
|
|
}
|
|
|
|
func parseResolver(s string) (Name, string, uint16, error) {
|
|
head, server, ok := strings.Cut(s, "+udp://")
|
|
if !ok {
|
|
return nil, "", 0, errors.New("invalid resolver scheme")
|
|
}
|
|
if server == "" {
|
|
return nil, "", 0, errors.New("empty resolver server")
|
|
}
|
|
|
|
spec, err := parseDomainSpec(head, "txt")
|
|
if err != nil {
|
|
return nil, "", 0, err
|
|
}
|
|
|
|
return spec.name, server, spec.rrType, nil
|
|
}
|