feat(ednsdiag): support custom DoH endpoint via --url
Allow overriding the provider preset with an explicit HTTPS DoH URL, including validation that custom endpoints apply only to DoH queries.
This commit is contained in:
@@ -129,6 +129,8 @@ func parseQueryArgs(args []string) (edns.QueryOptions, time.Duration, error) {
|
|||||||
options.Protocol = strings.ToLower(value)
|
options.Protocol = strings.ToLower(value)
|
||||||
case "provider":
|
case "provider":
|
||||||
options.Provider = strings.ToLower(value)
|
options.Provider = strings.ToLower(value)
|
||||||
|
case "url":
|
||||||
|
options.EndpointURL = value
|
||||||
case "method":
|
case "method":
|
||||||
options.Method = strings.ToLower(value)
|
options.Method = strings.ToLower(value)
|
||||||
case "timeout":
|
case "timeout":
|
||||||
@@ -178,5 +180,5 @@ func writeUsage(writer io.Writer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func writeQueryUsage(writer io.Writer) {
|
func writeQueryUsage(writer io.Writer) {
|
||||||
fmt.Fprintln(writer, "usage: ednsdiag query <domain> [type] [--protocol doh|dot] [--provider cloudflare|google|quad9|adguard] [--method post|get] [--timeout 5s]")
|
fmt.Fprintln(writer, "usage: ednsdiag query <domain> [type] [--protocol doh|dot] [--provider cloudflare|google|quad9|adguard] [--url https://host/dns-query] [--method post|get] [--timeout 5s]")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ type QueryOptions struct {
|
|||||||
Protocol string
|
Protocol string
|
||||||
Provider string
|
Provider string
|
||||||
Method string
|
Method string
|
||||||
|
EndpointURL string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Result struct {
|
type Result struct {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package edns
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Query(ctx context.Context, options QueryOptions) Result {
|
func Query(ctx context.Context, options QueryOptions) Result {
|
||||||
@@ -29,6 +30,18 @@ func Query(ctx context.Context, options QueryOptions) Result {
|
|||||||
result.Error = &ErrorInfo{Class: "input", Message: err.Error()}
|
result.Error = &ErrorInfo{Class: "input", Message: err.Error()}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
if options.EndpointURL != "" {
|
||||||
|
if options.Protocol != "doh" {
|
||||||
|
result.Error = &ErrorInfo{Class: "input", Message: "custom --url applies only to DoH"}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
parsed, err := url.Parse(options.EndpointURL)
|
||||||
|
if err != nil || parsed.Scheme != "https" || parsed.Hostname() == "" {
|
||||||
|
result.Error = &ErrorInfo{Class: "input", Message: fmt.Sprintf("invalid DoH endpoint URL %q", options.EndpointURL)}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
provider = Provider{ID: "custom", Profile: "custom", DoHURL: options.EndpointURL}
|
||||||
|
}
|
||||||
result.Resolver = ResolverInfo{Provider: provider.ID, Profile: provider.Profile}
|
result.Resolver = ResolverInfo{Provider: provider.ID, Profile: provider.Profile}
|
||||||
|
|
||||||
var response []byte
|
var response []byte
|
||||||
|
|||||||
Reference in New Issue
Block a user