Skip to content

Commit

Permalink
feat: support custom DoH/DoH3 url path
Browse files Browse the repository at this point in the history
  • Loading branch information
EkkoG committed Sep 27, 2024
1 parent 3fa4f0b commit 04b5de8
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 14 deletions.
2 changes: 1 addition & 1 deletion component/dns/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func New(dns *config.Dns, opt *NewOption) (s *Dns, err error) {

func (s *Dns) CheckUpstreamsFormat() error {
for _, upstream := range s.upstream {
_, _, _, err := ParseRawUpstream(upstream.Raw)
_, _, _, _, err := ParseRawUpstream(upstream.Raw)
if err != nil {
return err
}
Expand Down
19 changes: 13 additions & 6 deletions component/dns/upstream.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ func (s UpstreamScheme) ContainsTcp() bool {
}
}

func ParseRawUpstream(raw *url.URL) (scheme UpstreamScheme, hostname string, port uint16, err error) {
func ParseRawUpstream(raw *url.URL) (scheme UpstreamScheme, hostname string, port uint16, path string, err error) {
var __port string
var __path string
switch scheme = UpstreamScheme(raw.Scheme); scheme {
case upstreamScheme_TCP_UDP_Alias:
scheme = UpstreamScheme_TCP_UDP
Expand All @@ -66,32 +67,37 @@ func ParseRawUpstream(raw *url.URL) (scheme UpstreamScheme, hostname string, por
if __port == "" {
__port = "443"
}
__path = raw.Path
if __path == "" {
__path = "/dns-query"
}
case UpstreamScheme_QUIC, UpstreamScheme_TLS:
__port = raw.Port()
if __port == "" {
__port = "853"
}
default:
return "", "", 0, fmt.Errorf("unexpected scheme: %v", raw.Scheme)
return "", "", 0, "", fmt.Errorf("unexpected scheme: %v", raw.Scheme)
}
_port, err := strconv.ParseUint(__port, 10, 16)
if err != nil {
return "", "", 0, fmt.Errorf("failed to parse dns_upstream port: %v", err)
return "", "", 0, "", fmt.Errorf("failed to parse dns_upstream port: %v", err)
}
port = uint16(_port)
hostname = raw.Hostname()
return scheme, hostname, port, nil
return scheme, hostname, port, __path, nil
}

type Upstream struct {
Scheme UpstreamScheme
Hostname string
Port uint16
Path string
*netutils.Ip46
}

func NewUpstream(ctx context.Context, upstream *url.URL, resolverNetwork string) (up *Upstream, err error) {
scheme, hostname, port, err := ParseRawUpstream(upstream)
scheme, hostname, port, path, err := ParseRawUpstream(upstream)
if err != nil {
return nil, fmt.Errorf("%w: %v", ErrFormat, err)
}
Expand All @@ -118,6 +124,7 @@ func NewUpstream(ctx context.Context, upstream *url.URL, resolverNetwork string)
Scheme: scheme,
Hostname: hostname,
Port: port,
Path: path,
Ip46: ip46,
}, nil
}
Expand Down Expand Up @@ -145,7 +152,7 @@ func (u *Upstream) SupportedNetworks() (ipversions []consts.IpVersionStr, l4prot
}

func (u *Upstream) String() string {
return string(u.Scheme) + "://" + net.JoinHostPort(u.Hostname, strconv.Itoa(int(u.Port)))
return string(u.Scheme) + "://" + net.JoinHostPort(u.Hostname, strconv.Itoa(int(u.Port))) + u.Path
}

type UpstreamResolver struct {
Expand Down
12 changes: 5 additions & 7 deletions control/dns_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ func (c *DnsController) dialSend(invokingDepth int, req *udpRequest, data []byte
client := &http.Client{
Transport: roundTripper,
}
msg, err := sendHttpDNS(client, dialArgument.bestTarget.String(), upstream.Hostname, data)
msg, err := sendHttpDNS(client, dialArgument.bestTarget.String(), upstream.Hostname, upstream.Path, data)
if err != nil {
return err
}
Expand Down Expand Up @@ -700,7 +700,6 @@ func (c *DnsController) dialSend(invokingDepth int, req *udpRequest, data []byte
// msg id should set to 0 when transport over QUIC.
// thanks https://github.com/natesales/q/blob/1cb2639caf69bd0a9b46494a3c689130df8fb24a/transport/quic.go#L97
binary.BigEndian.PutUint16(data[0:2], 0)


msg, err := sendStreamDNS(stream, data)
if err != nil {
Expand Down Expand Up @@ -751,7 +750,7 @@ func (c *DnsController) dialSend(invokingDepth int, req *udpRequest, data []byte
client := http.Client{
Transport: &httpTransport,
}
msg, err := sendHttpDNS(&client, dialArgument.bestTarget.String(), upstream.Hostname, data)
msg, err := sendHttpDNS(&client, dialArgument.bestTarget.String(), upstream.Hostname, upstream.Path, data)
if err != nil {
return err
}
Expand Down Expand Up @@ -848,11 +847,11 @@ func (c *DnsController) dialSend(invokingDepth int, req *udpRequest, data []byte
return nil
}

func sendHttpDNS(client *http.Client, target string, host string, data []byte) (respMsg *dnsmessage.Msg, err error) {
func sendHttpDNS(client *http.Client, target string, host string, path string, data []byte) (respMsg *dnsmessage.Msg, err error) {
serverURL := url.URL{
Scheme: "https",
Host: target,
Path: "/dns-query",
Path: path,
}

req, err := http.NewRequest(http.MethodPost, serverURL.String(), bytes.NewReader(data))
Expand Down Expand Up @@ -909,8 +908,7 @@ func sendStreamDNS(stream io.ReadWriter, data []byte) (respMsg *dnsmessage.Msg,
}
var msg dnsmessage.Msg
if err = msg.Unpack(buf[:n]); err != nil {
return nil, err
return nil, err
}
return &msg, nil
}

0 comments on commit 04b5de8

Please sign in to comment.