cli

package
v0.0.0-...-61ee39e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 20, 2024 License: MIT Imports: 12 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var CommandQuery = &cobra.Command{
	Use:   "query domains... [flags]",
	Short: "Query DNS records from DoH servers",
	Long: `Query DNS records from DoH servers using the given domains and record type.
		
Users can specify which servers to use for the query, or use the default servers from Google, Cloudflare, and Quad9.
They can also specify a timeout for the query, which defaults to 30 seconds if not specified. Each server is queried
in parallel, and each domain is queried in parallel. Results are streamed to STDOUT as JSON newline delimited objects,
which can be piped to other commands (e.g. jq) or redirected to a file.`,
	Args: cobra.MinimumNArgs(1),
	RunE: func(cmd *cobra.Command, args []string) error {
		servers, err := cmd.Flags().GetStringSlice("servers")
		if err != nil {
			return fmt.Errorf("invalid servers: %w", err)
		}

		queryType := cmd.Flag("type").Value.String()

		timeout, err := cmd.Flags().GetDuration("timeout")
		if err != nil {
			return fmt.Errorf("invalid timeout: %w", err)
		}

		httpClient := cleanhttp.DefaultClient()

		resolverAddr, err := cmd.Flags().GetString("resolver-addr")
		if err != nil {
			return fmt.Errorf("invalid resolver address: %w", err)
		}

		resolverNetwork, err := cmd.Flags().GetString("resolver-network")
		if err != nil {
			return fmt.Errorf("invalid resolver network: %w", err)
		}

		if resolverAddr != "" {
			dialer := &net.Dialer{
				Resolver: &net.Resolver{
					PreferGo: true,
					Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
						d := net.Dialer{
							Timeout: timeout,
						}
						conn, err := d.DialContext(ctx, resolverNetwork, resolverAddr)
						if err != nil {
							return nil, fmt.Errorf("error dialing with custom resolver: %w", err)
						}
						return conn, nil
					},
				},
			}

			httpClient.Transport.(*http.Transport).DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
				return dialer.DialContext(ctx, network, addr)
			}
		}

		output := json.NewEncoder(cmd.OutOrStdout())

		var (
			ctx    context.Context    = cmd.Context()
			cancel context.CancelFunc = func() {}
		)

		if timeout != 0 {
			ctx, cancel = context.WithTimeout(cmd.Context(), timeout)
		}

		defer cancel()

		eg, gtx := errgroup.WithContext(ctx)

		for _, arg := range args {
			req := &dj.Request{
				Name: arg,
				Type: queryType,
			}

			for _, server := range servers {
				server := strings.TrimSpace(server)
				eg.Go(func() error {
					resp, err := doh.SimpleQuery(gtx, httpClient, server, req)
					if err != nil {
						return err
					}

					return output.Encode(&result{
						Server: server,
						Resp:   resp,
					})
				})

			}
		}

		if err := eg.Wait(); err != nil {
			return fmt.Errorf("encountered error while querying: %w", err)
		}

		return nil
	},
}
View Source
var CommandRoot = &cobra.Command{
	Use:   "doh",
	Short: `doh is a CLI for querying DNS records from DoH servers`,
}

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL