Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SVCB dohpath key #1359

Merged
merged 3 commits into from Apr 12, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions parse_test.go
Expand Up @@ -1652,6 +1652,8 @@ func TestParseSVCB(t *testing.T) {
`example.com. SVCB 16 foo.example.org. alpn=h2,h3-19 mandatory=ipv4hint,alpn ipv4hint=192.0.2.1`: `example.com. 3600 IN SVCB 16 foo.example.org. alpn="h2,h3-19" mandatory="ipv4hint,alpn" ipv4hint="192.0.2.1"`,
`example.com. SVCB 16 foo.example.org. alpn="f\\\\oo\\,bar,h2"`: `example.com. 3600 IN SVCB 16 foo.example.org. alpn="f\\\\oo\\,bar,h2"`,
`example.com. SVCB 16 foo.example.org. alpn=f\\\092oo\092,bar,h2`: `example.com. 3600 IN SVCB 16 foo.example.org. alpn="f\\\092oo\092,bar,h2"`,
// From draft-ietf-add-ddr-06
`_dns.example.net. SVCB 1 example.net. alpn=h2 dohpath=/dns-query{?dns}`: `_dns.example.net. 3600 IN SVCB 1 example.net. alpn="h2" dohpath="/dns-query{?dns}"`,
}
for s, o := range svcbs {
rr, err := NewRR(s)
Expand Down
78 changes: 71 additions & 7 deletions svcb.go
Expand Up @@ -13,7 +13,8 @@ import (
// SVCBKey is the type of the keys used in the SVCB RR.
type SVCBKey uint16

// Keys defined in draft-ietf-dnsop-svcb-https-08 Section 14.3.2.
// Keys defined in draft-ietf-dnsop-svcb-https-08 Section 14.3.2
// and draft-ietf-add-svcb-dns-02 Section 9.
ainar-g marked this conversation as resolved.
Show resolved Hide resolved
const (
SVCB_MANDATORY SVCBKey = iota
SVCB_ALPN
Expand All @@ -22,23 +23,28 @@ const (
SVCB_IPV4HINT
SVCB_ECHCONFIG
SVCB_IPV6HINT
SVCB_DOHPATH
ainar-g marked this conversation as resolved.
Show resolved Hide resolved

svcb_RESERVED SVCBKey = 65535
)

var svcbKeyToStringMap = map[SVCBKey]string{
// SVCBKeyToString is a map of strings for each SVCB key.
var SVCBKeyToString = map[SVCBKey]string{
SVCB_MANDATORY: "mandatory",
SVCB_ALPN: "alpn",
SVCB_NO_DEFAULT_ALPN: "no-default-alpn",
SVCB_PORT: "port",
SVCB_IPV4HINT: "ipv4hint",
SVCB_ECHCONFIG: "ech",
SVCB_IPV6HINT: "ipv6hint",
SVCB_DOHPATH: "dohpath",
}

var svcbStringToKeyMap = reverseSVCBKeyMap(svcbKeyToStringMap)
// StringToSVCBKey is the reverse of SVCBKeyToString, needed for string
// parsing.
var StringToSVCBKey = reverseSVCBKey(SVCBKeyToString)
ainar-g marked this conversation as resolved.
Show resolved Hide resolved

func reverseSVCBKeyMap(m map[SVCBKey]string) map[string]SVCBKey {
func reverseSVCBKey(m map[SVCBKey]string) map[string]SVCBKey {
n := make(map[string]SVCBKey, len(m))
for u, s := range m {
n[s] = u
Expand All @@ -50,7 +56,7 @@ func reverseSVCBKeyMap(m map[SVCBKey]string) map[string]SVCBKey {
// Returns an empty string for reserved keys.
// Accepts unassigned keys as well as experimental/private keys.
func (key SVCBKey) String() string {
if x := svcbKeyToStringMap[key]; x != "" {
if x := SVCBKeyToString[key]; x != "" {
return x
}
if key == svcb_RESERVED {
Expand All @@ -67,12 +73,12 @@ func svcbStringToKey(s string) SVCBKey {
a, err := strconv.ParseUint(s[3:], 10, 16)
// no leading zeros
// key shouldn't be registered
if err != nil || a == 65535 || s[3] == '0' || svcbKeyToStringMap[SVCBKey(a)] != "" {
if err != nil || a == 65535 || s[3] == '0' || SVCBKeyToString[SVCBKey(a)] != "" {
return svcb_RESERVED
}
return SVCBKey(a)
}
if key, ok := svcbStringToKeyMap[s]; ok {
if key, ok := StringToSVCBKey[s]; ok {
return key
}
return svcb_RESERVED
Expand Down Expand Up @@ -196,6 +202,8 @@ func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
return new(SVCBECHConfig)
case SVCB_IPV6HINT:
return new(SVCBIPv6Hint)
case SVCB_DOHPATH:
return new(SVCBDoHPath)
case svcb_RESERVED:
return nil
default:
Expand Down Expand Up @@ -669,6 +677,62 @@ func (s *SVCBIPv6Hint) copy() SVCBKeyValue {
}
}

// SVCBDoHPath pair is used to indicate the URI template that the
// clients may use to construct a DNS over HTTPS URI.
//
// See RFC xxxx (https://datatracker.ietf.org/doc/html/draft-ietf-add-svcb-dns-02)
// and RFC yyyy (https://datatracker.ietf.org/doc/html/draft-ietf-add-ddr-06).
//
// Basic use pattern for using the dohpath option together with an alpn
// option:
//
// s := new(dns.SVCB)
// s.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}
// e := new(dns.SVCBAlpn)
// e.Alpn = []string{"h2", "h3"}
ainar-g marked this conversation as resolved.
Show resolved Hide resolved
// p := new(dns.SVCBDoHPath)
// p.Template = "/dns-query{?dns}"
// s.Value = append(s.Value, e, p)
//
// The parsing currently only validates the length of Template.
// It doesn't validate that Template is a valid RFC 6570 URI template.
type SVCBDoHPath struct {
miekg marked this conversation as resolved.
Show resolved Hide resolved
Template string
}

func (*SVCBDoHPath) Key() SVCBKey { return SVCB_DOHPATH }
func (s *SVCBDoHPath) len() int { return len(s.Template) }

func (s *SVCBDoHPath) pack() ([]byte, error) {
if len(s.Template) > 255 {
ainar-g marked this conversation as resolved.
Show resolved Hide resolved
return nil, errors.New("dns: svcbdohpath: template too long")
}
return []byte(s.Template), nil
}

func (s *SVCBDoHPath) unpack(b []byte) error {
s.Template = string(b)
return nil
}

func (s *SVCBDoHPath) String() string {
return s.Template
}

func (s *SVCBDoHPath) parse(b string) error {
if len(b) > 255 {
return errors.New("dns: svcbdohpath: template too long")
}
s.Template = b
return nil
}

func (s *SVCBDoHPath) copy() SVCBKeyValue {
return &SVCBDoHPath{
Template: s.Template,
}
}

// SVCBLocal pair is intended for experimental/private use. The key is recommended
// to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER].
// Basic use pattern for creating a keyNNNNN option:
Expand Down
1 change: 1 addition & 0 deletions svcb_test.go
Expand Up @@ -18,6 +18,7 @@ func TestSVCB(t *testing.T) {
{`no-default-alpn`, ``},
{`ipv6hint`, `1::4:4:4:4,1::3:3:3:3`},
{`ech`, `YUdWc2JHOD0=`},
{`dohpath`, `/dns-query{?dns}`},
{`key65000`, `4\ 3`},
{`key65001`, `\"\ `},
{`key65002`, ``},
Expand Down