|
| 1 | +// Package providers ... |
| 2 | +package providers |
| 3 | + |
| 4 | +import ( |
| 5 | + "context" |
| 6 | + "crypto/tls" |
| 7 | + "math/rand" |
| 8 | + "net" |
| 9 | + |
| 10 | + "github.com/alphasoc/flightsim/simulator/encdns" |
| 11 | +) |
| 12 | + |
| 13 | +// Provider represents a DoT provider. addr and ctx are used to dial. |
| 14 | +type Provider struct { |
| 15 | + ctx context.Context |
| 16 | + addr string |
| 17 | +} |
| 18 | + |
| 19 | +// Providers supporting DoT. |
| 20 | +var providers = []encdns.ProviderType{ |
| 21 | + encdns.GoogleProvider, |
| 22 | + encdns.CloudFlareProvider, |
| 23 | + encdns.Quad9Provider, |
| 24 | + // OpenDNS does not, and does not plan to support DoT. |
| 25 | +} |
| 26 | + |
| 27 | +// NewRandom returns a 'random' Queryable provider. |
| 28 | +func NewRandom(ctx context.Context) encdns.Queryable { |
| 29 | + pIdx := encdns.ProviderType(rand.Intn(len(providers))) |
| 30 | + var p encdns.Queryable |
| 31 | + switch providers[pIdx] { |
| 32 | + case encdns.GoogleProvider: |
| 33 | + p = NewGoogle(ctx) |
| 34 | + case encdns.CloudFlareProvider: |
| 35 | + p = NewCloudFlare(ctx) |
| 36 | + case encdns.Quad9Provider: |
| 37 | + p = NewQuad9(ctx) |
| 38 | + } |
| 39 | + return p |
| 40 | +} |
| 41 | + |
| 42 | +// NewGoogle returns a *Provider for Google's DoT service. |
| 43 | +func NewGoogle(ctx context.Context) *Provider { |
| 44 | + return &Provider{ctx: ctx, addr: "dns.google:853"} |
| 45 | +} |
| 46 | + |
| 47 | +// NewGoogle returns a *Provider tied for CloudFlare's DoT service. |
| 48 | +func NewCloudFlare(ctx context.Context) *Provider { |
| 49 | + return &Provider{ctx: ctx, addr: "1dot1dot1dot1.cloudflare-dns.com:853"} |
| 50 | +} |
| 51 | + |
| 52 | +// NewGoogle returns a *Provider for Quad9's DoT service. |
| 53 | +func NewQuad9(ctx context.Context) *Provider { |
| 54 | + return &Provider{ctx: ctx, addr: "dns.quad9.net:853"} |
| 55 | +} |
| 56 | + |
| 57 | +// QueryTXT performs a DoT TXT lookup using Provider p, and returns a *encdns.Response and |
| 58 | +// an error. |
| 59 | +func (p *Provider) QueryTXT(ctx context.Context, domain string) (*encdns.Response, error) { |
| 60 | + d := tls.Dialer{} |
| 61 | + r := &net.Resolver{ |
| 62 | + PreferGo: true, |
| 63 | + Dial: func(ctx context.Context, network, addr string) (net.Conn, error) { |
| 64 | + return d.DialContext(p.ctx, "tcp", p.addr) |
| 65 | + }, |
| 66 | + } |
| 67 | + resp, err := r.LookupTXT(ctx, domain) |
| 68 | + return &encdns.Response{U: resp}, err |
| 69 | +} |
0 commit comments