svcb: doc updates (#1178)
The SVBC record didn't have a class, so add that and use struct literal to put it all on 1 one. Use `s` for SVCB records, and `h` for HTTPS to be more consistent. Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
parent
95dddd3867
commit
61a22d0ee6
104
svcb.go
104
svcb.go
|
@ -12,7 +12,7 @@ import (
|
||||||
|
|
||||||
type SVCBKey uint16
|
type SVCBKey uint16
|
||||||
|
|
||||||
// Keys defined in draft-ietf-dnsop-svcb-https-02 Section 11.1.2
|
// Keys defined in draft-ietf-dnsop-svcb-https-02 Section 11.1.2.
|
||||||
const (
|
const (
|
||||||
SVCB_MANDATORY SVCBKey = 0
|
SVCB_MANDATORY SVCBKey = 0
|
||||||
SVCB_ALPN SVCBKey = 1
|
SVCB_ALPN SVCBKey = 1
|
||||||
|
@ -173,8 +173,7 @@ func (rr *SVCB) parse(c *zlexer, o string) *ParseError {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeSVCBKeyValue returns an SVCBKeyValue struct with the key
|
// makeSVCBKeyValue returns an SVCBKeyValue struct with the key or nil for reserved keys.
|
||||||
// or nil for reserved keys.
|
|
||||||
func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
|
func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
|
||||||
switch key {
|
switch key {
|
||||||
case SVCB_MANDATORY:
|
case SVCB_MANDATORY:
|
||||||
|
@ -200,19 +199,16 @@ func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SVCB RR. See RFC xxxx (https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-00)
|
// SVCB RR. See RFC xxxx (https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-02).
|
||||||
|
|
||||||
// The one with the smallest priority should be given preference. Of those with
|
|
||||||
// equal priority, a random one should be preferred for load balancing.
|
|
||||||
type SVCB struct {
|
type SVCB struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Priority uint16
|
Priority uint16
|
||||||
Target string `dns:"domain-name"`
|
Target string `dns:"domain-name"`
|
||||||
Value []SVCBKeyValue `dns:"pairs"` // This must be empty if Priority is non-zero
|
Value []SVCBKeyValue `dns:"pairs"` // Value must be empty if Priority is non-zero.
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPS RR. Everything valid for SVCB applies to HTTPS as well
|
// HTTPS RR. Everything valid for SVCB applies to HTTPS as well.
|
||||||
// except that the HTTPS record is intended for use with the HTTP and HTTPS protocols.
|
// Except that the HTTPS record is intended for use with the HTTP and HTTPS protocols.
|
||||||
type HTTPS struct {
|
type HTTPS struct {
|
||||||
SVCB
|
SVCB
|
||||||
}
|
}
|
||||||
|
@ -228,33 +224,23 @@ func (rr *HTTPS) parse(c *zlexer, o string) *ParseError {
|
||||||
// SVCBKeyValue defines a key=value pair for the SVCB RR type.
|
// SVCBKeyValue defines a key=value pair for the SVCB RR type.
|
||||||
// An SVCB RR can have multiple SVCBKeyValues appended to it.
|
// An SVCB RR can have multiple SVCBKeyValues appended to it.
|
||||||
type SVCBKeyValue interface {
|
type SVCBKeyValue interface {
|
||||||
// Key returns the numerical key code.
|
Key() SVCBKey // Key returns the numerical key code.
|
||||||
Key() SVCBKey
|
pack() ([]byte, error) // pack returns the encoded value.
|
||||||
// pack returns the encoded value.
|
unpack([]byte) error // unpack sets the value.
|
||||||
pack() ([]byte, error)
|
String() string // String returns the string representation of the value.
|
||||||
// unpack sets the value.
|
parse(string) error // parse sets the value to the given string representation of the value.
|
||||||
unpack([]byte) error
|
copy() SVCBKeyValue // copy returns a deep-copy of the pair.
|
||||||
// String returns the string representation of the value.
|
len() int // len returns the length of value in the wire format.
|
||||||
String() string
|
|
||||||
// parse sets the value to the given string representation of the value.
|
|
||||||
parse(string) error
|
|
||||||
// copy returns a deep-copy of the pair.
|
|
||||||
copy() SVCBKeyValue
|
|
||||||
// len returns the length of value in the wire format.
|
|
||||||
len() int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SVCBMandatory pair adds to required keys that must be interpreted for the RR
|
// SVCBMandatory pair adds to required keys that must be interpreted for the RR
|
||||||
// to be functional.
|
// to be functional.
|
||||||
// Basic use pattern for creating a mandatory option:
|
// Basic use pattern for creating a mandatory option:
|
||||||
//
|
//
|
||||||
// o := new(dns.SVCB)
|
// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
|
||||||
// o.Hdr.Name = "."
|
|
||||||
// o.Hdr.Rrtype = dns.TypeSVCB
|
|
||||||
// e := new(dns.SVCBMandatory)
|
// e := new(dns.SVCBMandatory)
|
||||||
// e.Code = []uint16{65403}
|
// e.Code = []uint16{65403}
|
||||||
// o.Value = append(o.Value, e)
|
// s.Value = append(s.Value, e)
|
||||||
// // Then add key-value pair for key65403
|
|
||||||
type SVCBMandatory struct {
|
type SVCBMandatory struct {
|
||||||
Code []SVCBKey // Must not include mandatory
|
Code []SVCBKey // Must not include mandatory
|
||||||
}
|
}
|
||||||
|
@ -319,12 +305,10 @@ func (s *SVCBMandatory) copy() SVCBKeyValue {
|
||||||
// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
|
// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
|
||||||
// Basic use pattern for creating an alpn option:
|
// Basic use pattern for creating an alpn option:
|
||||||
//
|
//
|
||||||
// o := new(dns.HTTPS)
|
// h := &dns.HTTPS{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}}
|
||||||
// o.Hdr.Name = "."
|
|
||||||
// o.Hdr.Rrtype = dns.TypeHTTPS
|
|
||||||
// e := new(dns.SVCBAlpn)
|
// e := new(dns.SVCBAlpn)
|
||||||
// e.Alpn = []string{"h2", "http/1.1"}
|
// e.Alpn = []string{"h2", "http/1.1"}
|
||||||
// o.Value = append(o.Value, e)
|
// h.Value = append(o.Value, e)
|
||||||
type SVCBAlpn struct {
|
type SVCBAlpn struct {
|
||||||
Alpn []string
|
Alpn []string
|
||||||
}
|
}
|
||||||
|
@ -332,10 +316,6 @@ type SVCBAlpn struct {
|
||||||
func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN }
|
func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN }
|
||||||
func (s *SVCBAlpn) String() string { return strings.Join(s.Alpn, ",") }
|
func (s *SVCBAlpn) String() string { return strings.Join(s.Alpn, ",") }
|
||||||
|
|
||||||
// The spec requires the alpn keys including \ or , to be escaped.
|
|
||||||
// In practice, no standard key including those exists.
|
|
||||||
// Therefore those characters are not escaped.
|
|
||||||
|
|
||||||
func (s *SVCBAlpn) pack() ([]byte, error) {
|
func (s *SVCBAlpn) pack() ([]byte, error) {
|
||||||
// Liberally estimate the size of an alpn as 10 octets
|
// Liberally estimate the size of an alpn as 10 octets
|
||||||
b := make([]byte, 0, 10*len(s.Alpn))
|
b := make([]byte, 0, 10*len(s.Alpn))
|
||||||
|
@ -390,14 +370,10 @@ func (s *SVCBAlpn) copy() SVCBKeyValue {
|
||||||
// SVCBNoDefaultAlpn pair signifies no support for default connection protocols.
|
// SVCBNoDefaultAlpn pair signifies no support for default connection protocols.
|
||||||
// Basic use pattern for creating a no-default-alpn option:
|
// Basic use pattern for creating a no-default-alpn option:
|
||||||
//
|
//
|
||||||
// o := new(dns.SVCB)
|
// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
|
||||||
// o.Hdr.Name = "."
|
|
||||||
// o.Hdr.Rrtype = dns.SVCB
|
|
||||||
// e := new(dns.SVCBNoDefaultAlpn)
|
// e := new(dns.SVCBNoDefaultAlpn)
|
||||||
// o.Value = append(o.Value, e)
|
// s.Value = append(s.Value, e)
|
||||||
type SVCBNoDefaultAlpn struct {
|
type SVCBNoDefaultAlpn struct{}
|
||||||
// Empty
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*SVCBNoDefaultAlpn) Key() SVCBKey { return SVCB_NO_DEFAULT_ALPN }
|
func (*SVCBNoDefaultAlpn) Key() SVCBKey { return SVCB_NO_DEFAULT_ALPN }
|
||||||
func (*SVCBNoDefaultAlpn) copy() SVCBKeyValue { return &SVCBNoDefaultAlpn{} }
|
func (*SVCBNoDefaultAlpn) copy() SVCBKeyValue { return &SVCBNoDefaultAlpn{} }
|
||||||
|
@ -422,12 +398,10 @@ func (*SVCBNoDefaultAlpn) parse(b string) error {
|
||||||
// SVCBPort pair defines the port for connection.
|
// SVCBPort pair defines the port for connection.
|
||||||
// Basic use pattern for creating a port option:
|
// Basic use pattern for creating a port option:
|
||||||
//
|
//
|
||||||
// o := new(dns.SVCB)
|
// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
|
||||||
// o.Hdr.Name = "."
|
|
||||||
// o.Hdr.Rrtype = dns.SVCB
|
|
||||||
// e := new(dns.SVCBPort)
|
// e := new(dns.SVCBPort)
|
||||||
// e.Port = 80
|
// e.Port = 80
|
||||||
// o.Value = append(o.Value, e)
|
// s.Value = append(s.Value, e)
|
||||||
type SVCBPort struct {
|
type SVCBPort struct {
|
||||||
Port uint16
|
Port uint16
|
||||||
}
|
}
|
||||||
|
@ -466,14 +440,14 @@ func (s *SVCBPort) parse(b string) error {
|
||||||
// to the hinted IP address may be terminated and a new connection may be opened.
|
// to the hinted IP address may be terminated and a new connection may be opened.
|
||||||
// Basic use pattern for creating an ipv4hint option:
|
// Basic use pattern for creating an ipv4hint option:
|
||||||
//
|
//
|
||||||
// o := new(dns.HTTPS)
|
// h := &dns.HTTPS{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}}
|
||||||
// o.Hdr.Name = "."
|
|
||||||
// o.Hdr.Rrtype = dns.HTTPS
|
|
||||||
// e := new(dns.SVCBIPv4Hint)
|
// e := new(dns.SVCBIPv4Hint)
|
||||||
// e.Hint = []net.IP{net.IPv4(1,1,1,1).To4()}
|
// e.Hint = []net.IP{net.IPv4(1,1,1,1).To4()}
|
||||||
// // or
|
//
|
||||||
|
// Or
|
||||||
|
//
|
||||||
// e.Hint = []net.IP{net.ParseIP("1.1.1.1").To4()}
|
// e.Hint = []net.IP{net.ParseIP("1.1.1.1").To4()}
|
||||||
// o.Value = append(o.Value, e)
|
// h.Value = append(h.Value, e)
|
||||||
type SVCBIPv4Hint struct {
|
type SVCBIPv4Hint struct {
|
||||||
Hint []net.IP
|
Hint []net.IP
|
||||||
}
|
}
|
||||||
|
@ -505,7 +479,6 @@ func (s *SVCBIPv4Hint) unpack(b []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the string form of s, it returns "<nil>" if s is invalid.
|
|
||||||
func (s *SVCBIPv4Hint) String() string {
|
func (s *SVCBIPv4Hint) String() string {
|
||||||
str := make([]string, len(s.Hint))
|
str := make([]string, len(s.Hint))
|
||||||
for i, e := range s.Hint {
|
for i, e := range s.Hint {
|
||||||
|
@ -544,12 +517,10 @@ func (s *SVCBIPv4Hint) copy() SVCBKeyValue {
|
||||||
// SVCBECHConfig pair contains the ECHConfig structure defined in draft-ietf-tls-esni [RFC xxxx].
|
// SVCBECHConfig pair contains the ECHConfig structure defined in draft-ietf-tls-esni [RFC xxxx].
|
||||||
// Basic use pattern for creating an echconfig option:
|
// Basic use pattern for creating an echconfig option:
|
||||||
//
|
//
|
||||||
// o := new(dns.HTTPS)
|
// h := &dns.HTTPS{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}}
|
||||||
// o.Hdr.Name = "."
|
|
||||||
// o.Hdr.Rrtype = dns.HTTPS
|
|
||||||
// e := new(dns.SVCBECHConfig)
|
// e := new(dns.SVCBECHConfig)
|
||||||
// e.ECH = "/wH...="
|
// e.ECH = "/wH...="
|
||||||
// o.Value = append(o.Value, e)
|
// h.Value = append(h.Value, e)
|
||||||
type SVCBECHConfig struct {
|
type SVCBECHConfig struct {
|
||||||
ECH []byte
|
ECH []byte
|
||||||
}
|
}
|
||||||
|
@ -587,12 +558,10 @@ func (s *SVCBECHConfig) parse(b string) error {
|
||||||
// connection to the hinted IP address may be terminated and a new connection may be opened.
|
// connection to the hinted IP address may be terminated and a new connection may be opened.
|
||||||
// Basic use pattern for creating an ipv6hint option:
|
// Basic use pattern for creating an ipv6hint option:
|
||||||
//
|
//
|
||||||
// o := new(dns.HTTPS)
|
// h := &dns.HTTPS{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}}
|
||||||
// o.Hdr.Name = "."
|
|
||||||
// o.Hdr.Rrtype = dns.HTTPS
|
|
||||||
// e := new(dns.SVCBIPv6Hint)
|
// e := new(dns.SVCBIPv6Hint)
|
||||||
// e.Hint = []net.IP{net.ParseIP("2001:db8::1")}
|
// e.Hint = []net.IP{net.ParseIP("2001:db8::1")}
|
||||||
// o.Value = append(o.Value, e)
|
// h.Value = append(h.Value, e)
|
||||||
type SVCBIPv6Hint struct {
|
type SVCBIPv6Hint struct {
|
||||||
Hint []net.IP
|
Hint []net.IP
|
||||||
}
|
}
|
||||||
|
@ -627,7 +596,6 @@ func (s *SVCBIPv6Hint) unpack(b []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the string form of s, it returns "<nil>" if s is invalid.
|
|
||||||
func (s *SVCBIPv6Hint) String() string {
|
func (s *SVCBIPv6Hint) String() string {
|
||||||
str := make([]string, len(s.Hint))
|
str := make([]string, len(s.Hint))
|
||||||
for i, e := range s.Hint {
|
for i, e := range s.Hint {
|
||||||
|
@ -666,16 +634,14 @@ func (s *SVCBIPv6Hint) copy() SVCBKeyValue {
|
||||||
// to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER].
|
// to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER].
|
||||||
// Basic use pattern for creating a keyNNNNN option:
|
// Basic use pattern for creating a keyNNNNN option:
|
||||||
//
|
//
|
||||||
// o := new(dns.HTTPS)
|
// h := &dns.HTTPS{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}}
|
||||||
// o.Hdr.Name = "."
|
|
||||||
// o.Hdr.Rrtype = dns.HTTPS
|
|
||||||
// e := new(dns.SVCBLocal)
|
// e := new(dns.SVCBLocal)
|
||||||
// e.KeyCode = 65400
|
// e.KeyCode = 65400
|
||||||
// e.Data = []byte("abc")
|
// e.Data = []byte("abc")
|
||||||
// o.Value = append(o.Value, e)
|
// h.Value = append(h.Value, e)
|
||||||
type SVCBLocal struct {
|
type SVCBLocal struct {
|
||||||
KeyCode SVCBKey // Never 65535 or any assigned keys
|
KeyCode SVCBKey // Never 65535 or any assigned keys.
|
||||||
Data []byte // All byte sequences are allowed
|
Data []byte // All byte sequences are allowed.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SVCBLocal) Key() SVCBKey { return s.KeyCode }
|
func (s *SVCBLocal) Key() SVCBKey { return s.KeyCode }
|
||||||
|
|
Loading…
Reference in New Issue