doh

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: May 13, 2021 License: GPL-3.0 Imports: 11 Imported by: 0

README

go-doh-client

Build Status GoDoc Go Report Card codecov

This is a Go client library implementation of DNS over HTTPS (RFC8484).

Compliance with DNS specifications

This client library doesn't currently implement all of the DNS specifications.

It implements looking up the following records:

  • A
  • AAAA
  • CNAME
  • MX
  • NS
  • TXT
  • SRV
  • SOA
  • PTR

It also currently doesn't implement other query types than standard query, nor support for truncated messages. Full compliance, at least with RFC 1035, is something I'd like, though, so all of that should come in the future.

Usage

This client library should be as easy to use as any other DNS client library. The only difference is the transport layer it uses to perform lookups.

Here's a quick example:

package main

import (
	"log"

	"github.com/babolivier/go-doh-client"
)

func main() {
	resolver := doh.Resolver{
		Host:  "9.9.9.9", // Change this with your favourite DoH-compliant resolver.
		Class: doh.IN,
	}

	// Perform a A lookup on example.com
	a, _, err := resolver.LookupA("example.com")
	if err != nil {
		panic(err)
	}
	println(a[0].IP4) // 93.184.216.34

	// Perform a SRV lookup for e.g. a Matrix homeserver
	srv, _, err := resolver.LookupService("matrix", "tcp", "example.com")
	if err != nil {
		panic(err)
	}
	println(a[0].Target) // matrix.example.com
}

Why?

I grew quite interested in how the Internet works lately, which implies spending some time reading DNS-related RFCs. On top of that, DNS over HTTPS is something I'm interested in quite a lot for privacy reasons and because of how harder it is to censor than classic DNS, so I decided to give it a go. And also because my definition of "having fun during holidays" obviously involves implementing part of the DNS RFC.

Contribute

Contributions are more than welcome. I tried to make this library as friendly to hack on as possible, especially when the said hack aims to implement support for a new DNS record type. Here's an example of how to do so, which is the exhaustive changeset for the implementation of SOA records.

And of course, if you have any issue or feedback you want to report on, feel free to open an issue.

Documentation

Overview

Package doh implements client operations for DoH (DNS over HTTPS) lookups.

Index

Constants

View Source
const (
	// A implements the DNS A type.
	A DNSType = 1
	// NS implements the DNS NS type.
	NS = 2
	// CNAME implements the DNS CNAME type.
	CNAME = 5
	// SOA implements the DNS SOA type.
	SOA = 6
	// PTR implements the DNS PTR type.
	PTR = 12
	// MX implements the DNS MX type.
	MX = 15
	// TXT implements the DNS TXT type.
	TXT = 16
	// AAAA implements the DNS AAAA type.
	AAAA = 28
	// SRV implements the DNS SRV type.
	SRV = 33
)
View Source
const (
	// IN implement the DNS Internet class.
	IN DNSClass = 1
	// CS implements the DNS CSNET class.
	CS = 2
	// CH implements the DNS CH class.
	CH = 3
	// HS implements the DNS Hesiod class.
	HS = 4
	// ANYCLASS implements the DNS * QCLASS.
	ANYCLASS = 255
)

Variables

View Source
var ErrFormatError = errors.New("Format error")

ErrFormatError means that the name server was unable to interpret the query.

View Source
var ErrNameError = errors.New("Name error")

ErrNameError means that the domain name referenced in the query does not exist.

View Source
var ErrNotAResponse = errors.New("the message the server sent us isn't a response")

ErrNotAResponse means that the server responded with a message that isn't a response.

View Source
var ErrNotIN = errors.New("class must be IN (Internet) (or ANYCLASS (*), which includes IN)")

ErrNotIN means that the lookup can only be performed with the DNS class IN (e.g. A, AAAA).

View Source
var ErrNotImplemented = errors.New("Not implemented")

ErrNotImplemented means that the name server does not support the requested kind of query.

View Source
var ErrNotStandardQuery = errors.New("only standard queries are supported")

ErrNotStandardQuery means that the server responded with an OPCODE header that isn't a standard query, which is the only value currently supported.

View Source
var ErrRefused = errors.New("Refused")

ErrRefused means that The name server refuses to perform the specified operation for policy reasons. For example, a name server may not wish to provide the information to the particular requester, or a name server may not wish to perform a particular operation (e.g., zone transfer) for particular data.

View Source
var ErrServerFailure = errors.New("Server failure")

ErrServerFailure means that The name server was unable to process this query due to a problem with the name server.

View Source
var ErrTruncated = errors.New("truncated messages aren't supported")

ErrTruncated means that the message is truncated, which isn't currently supported.

Functions

This section is empty.

Types

type AAAARecord

type AAAARecord struct {
	IP6 string
}

AAAARecord implements the DNS AAAA record.

type ARecord

type ARecord struct {
	IP4 string
}

ARecord implements the DNS A record.

type CNAMERecord

type CNAMERecord struct {
	CNAME string
}

CNAMERecord implements the DNS CNAME record.

type DNSClass

type DNSClass uint16

DNSClass implements DNS classes.

type DNSType

type DNSType uint16

DNSType implements DNS values.

type MXRecord

type MXRecord net.MX

MXRecord implements the DNS MX record.

type NSRecord

type NSRecord net.NS

NSRecord implements the DNS NS record.

type PTRRecord

type PTRRecord struct {
	PTR string
}

PTRRecord implements the DNS PTR record.

type Resolver

type Resolver struct {
	// The host to send DoH requests to.
	Host string
	// The DNS class to lookup with, must be one of IN, CS, CH, HS or ANYCLASS.
	// As a hint, the most used class nowadays is IN (Internet).
	Class  DNSClass
	Client *http.Client
}

Resolver handles lookups.

func (*Resolver) LookupA

func (r *Resolver) LookupA(fqdn string) (recs []*ARecord, ttls []uint32, err error)

LookupA performs a DoH lookup on A records for the given FQDN. Returns records and TTLs such that ttls[0] is the TTL for recs[0], and so on. Returns an error if something went wrong at the network level, or when parsing the response headers, or if the resolver's class isn't IN.

func (*Resolver) LookupAAAA

func (r *Resolver) LookupAAAA(fqdn string) (recs []*AAAARecord, ttls []uint32, err error)

LookupAAAA performs a DoH lookup on AAAA records for the given FQDN. Returns records and TTLs such that ttls[0] is the TTL for recs[0], and so on. Returns an error if something went wrong at the network level, or when parsing the response headers, or if the resolver's class isn't IN.

func (*Resolver) LookupCNAME

func (r *Resolver) LookupCNAME(fqdn string) (recs []*CNAMERecord, ttls []uint32, err error)

LookupCNAME performs a DoH lookup on CNAME records for the given FQDN. Returns records and TTLs such that ttls[0] is the TTL for recs[0], and so on. Returns an error if something went wrong at the network level, or when parsing the response headers.

func (*Resolver) LookupMX

func (r *Resolver) LookupMX(fqdn string) (recs []*MXRecord, ttls []uint32, err error)

LookupMX performs a DoH lookup on CNAME records for the given FQDN. Returns records and TTLs such that ttls[0] is the TTL for recs[0], and so on. Returns an error if something went wrong at the network level, or when parsing the response headers.

func (*Resolver) LookupNS

func (r *Resolver) LookupNS(fqdn string) (recs []*NSRecord, ttls []uint32, err error)

LookupNS performs a DoH lookup on CNAME records for the given FQDN. Returns records and TTLs such that ttls[0] is the TTL for recs[0], and so on. Returns an error if something went wrong at the network level, or when parsing the response headers.

func (*Resolver) LookupPTR

func (r *Resolver) LookupPTR(fqdn string) (recs []*PTRRecord, ttls []uint32, err error)

LookupPTR performs a DoH lookup on PTR records for the given FQDN. Returns records and TTLs such that ttls[0] is the TTL for recs[0], and so on. Returns an error if something went wrong at the network level, or when parsing the response headers.

func (*Resolver) LookupSOA

func (r *Resolver) LookupSOA(fqdn string) (recs []*SOARecord, ttls []uint32, err error)

LookupSOA performs a DoH lookup on SOA records for the given FQDN. Returns records and TTLs such that ttls[0] is the TTL for recs[0], and so on. Returns an error if something went wrong at the network level, or when parsing the response headers.

func (*Resolver) LookupSRV

func (r *Resolver) LookupSRV(fqdn string) (recs []*SRVRecord, ttls []uint32, err error)

LookupSRV performs a DoH lookup on SRV records for the given FQDN. Returns records and TTLs such that ttls[0] is the TTL for recs[0], and so on. Returns an error if something went wrong at the network level, or when parsing the response headers.

func (*Resolver) LookupService

func (r *Resolver) LookupService(service, network, domain string) (recs []*SRVRecord, ttls []uint32, err error)

LookupService performs a DoH lookup on SRV records for the given service, network and domain. network's value is expected to be in the likes of "udp", "tcp" and so on. Under the hood, it builds a FQDN of the form _service._network.domain and calls r.LookupSRV with it. Returns records and TTLs such that ttls[0] is the TTL for recs[0], and so on. Returns an error if something went wrong at the network level, or when parsing the response headers.

func (*Resolver) LookupTXT

func (r *Resolver) LookupTXT(fqdn string) (recs []*TXTRecord, ttls []uint32, err error)

LookupTXT performs a DoH lookup on TXT records for the given FQDN. Returns records and TTLs such that ttls[0] is the TTL for recs[0], and so on. Returns an error if something went wrong at the network level, or when parsing the response headers.

type SOARecord

type SOARecord struct {
	PrimaryNS   string
	RespMailbox string
	Serial      uint32
	Refresh     int32
	Retry       int32
	Expire      int32
	Minimum     uint32
}

SOARecord implements the DNS SOA record.

type SRVRecord

type SRVRecord net.SRV

SRVRecord implements the DNS SRV record.

type TXTRecord

type TXTRecord struct {
	TXT string
}

TXTRecord implements the DNS TXT record.

Jump to

Keyboard shortcuts

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