diff --git a/.agents/skills/encrypted-dns-skill/cmd/ednsdiag/main.go b/.agents/skills/encrypted-dns-skill/cmd/ednsdiag/main.go index f6761d0..7e05ef4 100644 --- a/.agents/skills/encrypted-dns-skill/cmd/ednsdiag/main.go +++ b/.agents/skills/encrypted-dns-skill/cmd/ednsdiag/main.go @@ -129,6 +129,8 @@ func parseQueryArgs(args []string) (edns.QueryOptions, time.Duration, error) { options.Protocol = strings.ToLower(value) case "provider": options.Provider = strings.ToLower(value) + case "url": + options.EndpointURL = value case "method": options.Method = strings.ToLower(value) case "timeout": @@ -178,5 +180,5 @@ func writeUsage(writer io.Writer) { } func writeQueryUsage(writer io.Writer) { - fmt.Fprintln(writer, "usage: ednsdiag query [type] [--protocol doh|dot] [--provider cloudflare|google|quad9|adguard] [--method post|get] [--timeout 5s]") + fmt.Fprintln(writer, "usage: ednsdiag query [type] [--protocol doh|dot] [--provider cloudflare|google|quad9|adguard] [--url https://host/dns-query] [--method post|get] [--timeout 5s]") } diff --git a/.agents/skills/encrypted-dns-skill/internal/edns/model.go b/.agents/skills/encrypted-dns-skill/internal/edns/model.go index a3cea57..e73d793 100644 --- a/.agents/skills/encrypted-dns-skill/internal/edns/model.go +++ b/.agents/skills/encrypted-dns-skill/internal/edns/model.go @@ -6,6 +6,7 @@ type QueryOptions struct { Protocol string Provider string Method string + EndpointURL string } type Result struct { diff --git a/.agents/skills/encrypted-dns-skill/internal/edns/query.go b/.agents/skills/encrypted-dns-skill/internal/edns/query.go index f98dc48..16b5015 100644 --- a/.agents/skills/encrypted-dns-skill/internal/edns/query.go +++ b/.agents/skills/encrypted-dns-skill/internal/edns/query.go @@ -3,6 +3,7 @@ package edns import ( "context" "fmt" + "net/url" ) 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()} 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} var response []byte