Andrey Meshkov f1791135af Sync v2.11.0
2024-12-05 14:19:25 +03:00

122 lines
2.8 KiB
Go

package dnsserver
import (
"fmt"
"net"
"slices"
)
// Protocol is a DNS protocol.
type Protocol uint8
// Protocol values.
const (
// NOTE: DO NOT change the numerical values or use iota, because other
// packages and modules may depend on the numerical values. These numerical
// values are a part of the API.
// ProtoInvalid is the invalid default value.
ProtoInvalid Protocol = 0
// ProtoDNS is plain DNS.
ProtoDNS Protocol = 8
// ProtoDoH is DNS-over-HTTPS.
ProtoDoH Protocol = 3
// ProtoDoQ is DNS-over-QUIC.
ProtoDoQ Protocol = 4
// ProtoDoT is DNS-over-TLS.
ProtoDoT Protocol = 5
// ProtoDNSCrypt is DNSCrypt.
ProtoDNSCrypt Protocol = 9
)
// String implements the fmt.Stringer interface for Protocol.
func (p Protocol) String() (s string) {
switch p {
case ProtoDNS:
return "dns"
case ProtoDoH:
return "doh"
case ProtoDoQ:
return "doq"
case ProtoDoT:
return "dot"
case ProtoDNSCrypt:
return "dnscrypt"
default:
return fmt.Sprintf("!bad_protocol_%d", p)
}
}
// ALPN returns the application-layer negotiation strings for p. For protocols
// with no ALPN it returns nil.
func (p Protocol) ALPN() (alpn []string) {
switch p {
case ProtoDoT:
return []string{"dot"}
case ProtoDoQ:
return []string{nextProtoDoQ}
case ProtoDoH:
return slices.Clone(NextProtoDoH3)
default:
return nil
}
}
// HasPaddingSupport returns true if the protocol supports EDNS0 padding. For
// DoQ and DoH3 the padding should be added with QUIC, but as long as we can't
// control it yet, we add DoQ protocol here.
// TODO(d.kolyshev): Remove DoQ from this list.
func (p Protocol) HasPaddingSupport() (ok bool) {
return p.IsStdEncrypted()
}
// IsStdEncrypted returns true if the protocol is one of the standard encrypted
// DNS protocol as defined by an RFC.
func (p Protocol) IsStdEncrypted() (ok bool) {
return p == ProtoDoT || p == ProtoDoH || p == ProtoDoQ
}
// Network is a enum with net protocols TCP and UDP.
// Used for a kind of validation.
type Network string
// Network enum members. Note that we use "tcp" and "udp" strings so that
// we could use these constants when calling golang net package functions.
const (
NetworkTCP Network = "tcp"
NetworkUDP Network = "udp"
NetworkAny Network = ""
)
// CanTCP returns true if this Network supports TCP.
func (n Network) CanTCP() (ok bool) {
return n == NetworkAny || n == NetworkTCP
}
// CanUDP returns true if this Network supports UDP.
func (n Network) CanUDP() (ok bool) {
return n == NetworkAny || n == NetworkUDP
}
// NetworkFromAddr returns NetworkTCP or NetworkUDP depending on the address.
func NetworkFromAddr(addr net.Addr) (network Network) {
switch addr.Network() {
case "udp":
return NetworkUDP
case "tcp":
return NetworkTCP
default:
panic(fmt.Sprintf("unexpected network type %s", addr.Network()))
}
}
const (
// DNSHeaderSize is the DNS query header size.
DNSHeaderSize = 12
)