dnsmsg

package
v0.0.0-...-87137bd Latest Latest
Warning

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

Go to latest
Published: Nov 8, 2024 License: AGPL-3.0 Imports: 19 Imported by: 0

Documentation

Overview

Package dnsmsg contains common constants, functions, and types for inspecting and constructing DNS messages.

TODO(a.garipov): Consider moving all or some of this stuff to module golibs.

Index

Constants

View Source
const DefaultEDNSUDPSize = 4096

DefaultEDNSUDPSize is the default size used for EDNS content.

See https://datatracker.ietf.org/doc/html/rfc6891#section-6.2.5.

View Source
const MaxTXTStringLen int = 255

MaxTXTStringLen is the maximum length of a single string within a TXT resource record.

See also https://datatracker.ietf.org/doc/html/rfc6763#section-6.1.

View Source
const ServFailMaxCacheTTL = 30

ServFailMaxCacheTTL is the maximum time-to-live value for caching SERVFAIL responses in seconds. It's consistent with the upper constraint of 5 minutes given by RFC 2308.

See https://datatracker.ietf.org/doc/html/rfc2308#section-7.1.

Variables

This section is empty.

Functions

func Clone

func Clone(msg *dns.Msg) (clone *dns.Msg)

Clone returns a new *Msg which is a deep copy of msg. Use this instead of msg.Copy, because the latter does not actually produce a deep copy of msg.

See https://github.com/miekg/dns/issues/1351.

TODO(a.garipov): See if we can also decrease allocations for such cases by modifying more of the original code.

func ECSFromMsg

func ECSFromMsg(msg *dns.Msg) (subnet netip.Prefix, scope uint8, err error)

ECSFromMsg returns the EDNS Client Subnet option information from msg, if any. If there is none, it returns netip.Prefix{}. msg must not be nil. err is not nil only if msg contains a malformed EDNS Client Subnet option or the address family is unsupported (that is, neither IPv4 nor IPv6). Any error returned from ECSFromMsg will have the underlying type of BadECSError.

func FindLowestTTL

func FindLowestTTL(msg *dns.Msg) (ttl uint32)

FindLowestTTL gets the lowest TTL among all DNS message's RRs.

func IsDO

func IsDO(msg *dns.Msg) (ok bool)

IsDO returns true if msg has an EDNS option pseudosection and that pseudosection has the DNSSEC OK (DO) bit set.

func SetMinTTL

func SetMinTTL(r *dns.Msg, minTTL uint32)

SetMinTTL overrides TTL values of all answer records according to the min TTL.

Types

type BadECSError

type BadECSError struct {
	Err error
}

BadECSError is returned by functions that work with EDNS Client Subnet option when the data in the option is invalid.

func (BadECSError) Error

func (err BadECSError) Error() (msg string)

Error implements the error interface for BadECSError.

func (BadECSError) IsSentryReportable

func (err BadECSError) IsSentryReportable() (ok bool)

IsSentryReportable implements the [errcoll.SentryReportableError] interface for BadECSError.

func (BadECSError) Unwrap

func (err BadECSError) Unwrap() (unwrapped error)

Unwrap implements the errors.Wrapper interface for BadECSError.

type BlockingMode

type BlockingMode interface {
	// contains filtered or unexported methods
}

BlockingMode is a sum type of all possible ways to construct blocked or modified responses. See the following types:

type BlockingModeCustomIP

type BlockingModeCustomIP struct {
	// IPv4 is a slice of valid IPv4 addresses used in responses to A requests.
	IPv4 []netip.Addr

	// IPv6 is a slice of valid IPv6 addresses used in responses to AAAA
	// requests.
	IPv6 []netip.Addr
}

BlockingModeCustomIP makes the dnsmsg.Constructor return responses with custom IP addresses to A and AAAA requests. For all other types of requests, as well as in case the address corresponding to IP version is not set, it returns a response with no answers (aka NODATA).

type BlockingModeNXDOMAIN

type BlockingModeNXDOMAIN struct{}

BlockingModeNXDOMAIN makes the dnsmsg.Constructor return responses with code NXDOMAIN.

type BlockingModeNullIP

type BlockingModeNullIP struct{}

BlockingModeNullIP makes the dnsmsg.Constructor return a null-IP response to A and AAAA requests. For all other types of requests, it returns a response with no answers (aka NODATA).

type BlockingModeREFUSED

type BlockingModeREFUSED struct{}

BlockingModeREFUSED makes the dnsmsg.Constructor return responses with code REFUSED.

type Class

type Class = uint16

Class is a semantic alias for uint16 values when they are used as a DNS class code.

type Cloner

type Cloner struct {
	// contains filtered or unexported fields
}

Cloner is a pool that can clone common parts of DNS messages with fewer allocations.

TODO(a.garipov): Use in filtering when cloning a [filter.ResultModifiedResponse] message.

TODO(a.garipov): Use in Constructor.

func NewCloner

func NewCloner(stat ClonerStat) (c *Cloner)

NewCloner returns a new properly initialized *Cloner.

func (*Cloner) Clone

func (c *Cloner) Clone(msg *dns.Msg) (clone *dns.Msg)

Clone returns a deep clone of msg.

func (*Cloner) Dispose

func (c *Cloner) Dispose(resp *dns.Msg)

Dispose implements the dnsserver.Disposer interface for *Cloner. It returns structures from resp into c's pools. Neither resp nor any of its parts must be used after this.

type ClonerStat

type ClonerStat interface {
	// OnClone is called on [Cloner.Clone] calls.  isFull is true if the clone
	// was full.
	OnClone(isFull bool)
}

ClonerStat is an interface for entities that collect statistics about a Cloner.

All methods must be safe for concurrent use.

type Constructor

type Constructor struct {
	// contains filtered or unexported fields
}

Constructor creates DNS messages for blocked or modified responses. It must be created using NewConstructor.

func NewConstructor

func NewConstructor(conf *ConstructorConfig) (c *Constructor, err error)

NewConstructor returns a properly initialized constructor using conf.

func (*Constructor) AddEDE

func (c *Constructor) AddEDE(req, resp *dns.Msg, code uint16)

AddEDE adds an Extended DNS Error (EDE) option to the blocked response message, if the feature is enabled in the Constructor and the request indicates EDNS support. It does not overwrite EDE if there already is one. req and resp must not be nil.

func (*Constructor) AppendDebugExtra

func (c *Constructor) AppendDebugExtra(req, resp *dns.Msg, str string) (err error)

AppendDebugExtra appends to response message a DNS TXT extra with CHAOS class.

func (*Constructor) Cloner

func (c *Constructor) Cloner() (cloner *Cloner)

Cloner returns the constructor's Cloner.

func (*Constructor) NewAnswerA

func (c *Constructor) NewAnswerA(fqdn string, ip netip.Addr) (rr *dns.A, err error)

NewAnswerA returns a new resource record with the given IPv4 address and fqdn. fqdn is the fully-qualified name and must not be empty. ip must be an IPv4 address. If ip is a zero netip.Addr, it is replaced by an unspecified (aka null) IP, 0.0.0.0.

TODO(a.garipov): Use FQDN in all other answer constructors.

func (*Constructor) NewAnswerAAAA

func (c *Constructor) NewAnswerAAAA(fqdn string, ip netip.Addr) (rr *dns.AAAA, err error)

NewAnswerAAAA returns a new resource record with the given IPv6 address and fqdn. fqdn is the fully-qualified name and must not be empty. ip must be an IPv6 address. If ip is a zero netip.Addr, it is replaced by an unspecified (aka null) IP, [::].

func (*Constructor) NewAnswerCNAME

func (c *Constructor) NewAnswerCNAME(req *dns.Msg, target string) (rr *dns.CNAME)

NewAnswerCNAME returns a new resource record of CNAME type.

func (*Constructor) NewAnswerHTTPS

func (c *Constructor) NewAnswerHTTPS(req *dns.Msg, svcb *rules.DNSSVCB) (ans *dns.HTTPS)

NewAnswerHTTPS returns a properly initialized HTTPS resource record.

See the comment on NewAnswerSVCB for a list of current restrictions on parameter values.

func (*Constructor) NewAnswerMX

func (c *Constructor) NewAnswerMX(req *dns.Msg, mx *rules.DNSMX) (rr *dns.MX)

NewAnswerMX returns a new resource record of MX type.

func (*Constructor) NewAnswerPTR

func (c *Constructor) NewAnswerPTR(req *dns.Msg, ptr string) (rr *dns.PTR)

NewAnswerPTR returns a new resource record of PTR type.

func (*Constructor) NewAnswerSRV

func (c *Constructor) NewAnswerSRV(req *dns.Msg, srv *rules.DNSSRV) (rr *dns.SRV)

NewAnswerSRV returns a new resource record of SRV type.

func (*Constructor) NewAnswerSVCB

func (c *Constructor) NewAnswerSVCB(req *dns.Msg, svcb *rules.DNSSVCB) (ans *dns.SVCB)

NewAnswerSVCB returns a properly initialized SVCB resource record.

Currently, there are several restrictions on how the parameters are parsed. Firstly, the parsing of non-contiguous values isn't supported. Secondly, the parsing of value-lists is not supported either.

ipv4hint=127.0.0.1             // Supported.
ipv4hint="127.0.0.1"           // Unsupported.
ipv4hint=127.0.0.1,127.0.0.2   // Unsupported.
ipv4hint="127.0.0.1,127.0.0.2" // Unsupported.

TODO(a.garipov): Support all of these.

func (*Constructor) NewAnswerTXT

func (c *Constructor) NewAnswerTXT(req *dns.Msg, strs []string) (rr *dns.TXT, err error)

NewAnswerTXT returns a new resource record of TXT type.

func (*Constructor) NewBlockedNullIPResp

func (c *Constructor) NewBlockedNullIPResp(req *dns.Msg) (resp *dns.Msg, err error)

NewBlockedNullIPResp returns a blocked A or AAAA DNS response message with an unspecified (aka null) IP address. The TTL of the record is set to the constructor's FilteredResponseTTL.

func (*Constructor) NewBlockedResp

func (c *Constructor) NewBlockedResp(req *dns.Msg) (msg *dns.Msg, err error)

NewBlockedResp returns a blocked response DNS message based on the constructor's blocking mode.

func (*Constructor) NewBlockedRespIP

func (c *Constructor) NewBlockedRespIP(req *dns.Msg, ips ...netip.Addr) (msg *dns.Msg, err error)

NewBlockedRespIP returns an A or AAAA DNS response message with the given IP addresses. The TTL of each record is set to c.FilteredResponseTTL. ips should not contain zero values due to the extended error code semantics, use [NewBlockedNullIPResp] for this case.

TODO(a.garipov): Consider merging with [NewRespIP] if AddEDE with the Forged Answer code isn't used again.

func (*Constructor) NewBlockedRespRCode

func (c *Constructor) NewBlockedRespRCode(req *dns.Msg, rc RCode) (resp *dns.Msg)

NewBlockedRespRCode returns a blocked response DNS message with given response code.

TODO(e.burkov): Add SOA records to the response, like in Constructor.NewRespRCode.

func (*Constructor) NewDDRTemplate

func (c *Constructor) NewDDRTemplate(
	proto dnsserver.Protocol,
	resolverName string,
	dohPath string,
	ipv4Hints []netip.Addr,
	ipv6Hints []netip.Addr,
	port uint16,
	prio uint16,
) (rr *dns.SVCB)

NewDDRTemplate returns a single Discovery of Designated Resolvers response resource record template specific for a resolver. The returned resource record doesn't specify a name in its header since it may differ between requests, so it's not a valid record as is.

If the IP address arguments aren't empty, their elements will be added into the appropriate hints. Those arguments are assumed to be of the correct protocol version.

proto must be a standard encrypted protocol, as defined by dnsserver.Protocol.IsStdEncrypted.

TODO(a.garipov): Remove the dependency on package dnsserver.

func (*Constructor) NewResp

func (c *Constructor) NewResp(req *dns.Msg) (resp *dns.Msg)

NewResp creates a response DNS message for req and sets all necessary flags and fields. resp contains no resource records.

func (*Constructor) NewRespIP

func (c *Constructor) NewRespIP(req *dns.Msg, ips ...netip.Addr) (msg *dns.Msg, err error)

NewRespIP returns an A or AAAA DNS response message with the given IP addresses. If any IP address is nil, it is replaced by an unspecified (aka null) IP. The TTL is also set to c.FilteredResponseTTL.

func (*Constructor) NewRespRCode

func (c *Constructor) NewRespRCode(req *dns.Msg, rc RCode) (resp *dns.Msg)

NewRespRCode returns a response DNS message with given response code and a predefined authority section.

Use dns.RcodeSuccess for a proper NODATA response, see https://www.rfc-editor.org/rfc/rfc2308#section-2.2.

func (*Constructor) NewRespTXT

func (c *Constructor) NewRespTXT(req *dns.Msg, strs ...string) (msg *dns.Msg, err error)

NewRespTXT returns a DNS TXT response message with the given strings as content. The TTL of the TXT answer is set to c.FilteredResponseTTL.

type ConstructorConfig

type ConstructorConfig struct {
	// Cloner used to clone DNS messages.  It must not be nil.
	Cloner *Cloner

	// StructuredErrors is the configuration for the experimental Structured DNS
	// Errors feature.  It must not be nil.  If enabled,
	// [ConstructorConfig.Enabled] should also be true.
	StructuredErrors *StructuredDNSErrorsConfig

	// BlockingMode is the blocking mode to use in
	// [Constructor.NewBlockedRespMsg].  It must not be nil.
	BlockingMode BlockingMode

	// FilteredResponseTTL is the time-to-live value used for responses created
	// by this message constructor.  It must be non-negative.
	FilteredResponseTTL time.Duration

	// EDEEnabled enables the addition of the Extended DNS Error (EDE) codes.
	EDEEnabled bool
}

ConstructorConfig is a configuration for the constructor of DNS messages.

type ECS

type ECS struct {
	// Location is the GeoIP location data about the IP address from the
	// request's ECS data, if any.
	Location *geoip.Location

	// Subnet is the source subnet.
	Subnet netip.Prefix

	// Scope is the scope prefix.
	Scope uint8
}

ECS is the content of the EDNS Client Subnet option of a DNS message.

See https://datatracker.ietf.org/doc/html/rfc7871#section-6.

type EmptyClonerStat

type EmptyClonerStat struct{}

EmptyClonerStat is a ClonerStat implementation that does nothing.

func (EmptyClonerStat) OnClone

func (EmptyClonerStat) OnClone(_ bool)

OnClone implements the ClonerStat interface for EmptyClonerStat.

type RCode

type RCode = uint16

RCode is a semantic alias for uint16 values when they are used as a DNS response code RCODE.

See https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6.

type RRType

type RRType = uint16

RRType is a semantic alias for uint16 values when they are used as a DNS resource record (RR) type.

See https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4.

type StructuredDNSErrorsConfig

type StructuredDNSErrorsConfig struct {
	// Justification for this particular DNS filtering.  It must not be empty.
	Justification string

	// Organization is an optional description of the organization.
	Organization string

	// Contact information for the DNS service.  It must not be empty.  All
	// items must not be nil and must be valid mailto, sips, or tel URLs.
	Contact []*url.URL

	// Enabled, if true, enables the experimental Structured DNS Errors feature.
	Enabled bool
}

StructuredDNSErrorsConfig is the configuration structure for the experimental Structured DNS Errors feature.

See https://www.ietf.org/archive/id/draft-ietf-dnsop-structured-dns-error-09.html.

TODO(a.garipov): Add sub-error?

Jump to

Keyboard shortcuts

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