svcb.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. package dns
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "errors"
  6. "net"
  7. "sort"
  8. "strconv"
  9. "strings"
  10. )
  11. // SVCBKey is the type of the keys used in the SVCB RR.
  12. type SVCBKey uint16
  13. // Keys defined in draft-ietf-dnsop-svcb-https-01 Section 12.3.2.
  14. const (
  15. SVCB_MANDATORY SVCBKey = 0
  16. SVCB_ALPN SVCBKey = 1
  17. SVCB_NO_DEFAULT_ALPN SVCBKey = 2
  18. SVCB_PORT SVCBKey = 3
  19. SVCB_IPV4HINT SVCBKey = 4
  20. SVCB_ECHCONFIG SVCBKey = 5
  21. SVCB_IPV6HINT SVCBKey = 6
  22. svcb_RESERVED SVCBKey = 65535
  23. )
  24. var svcbKeyToStringMap = map[SVCBKey]string{
  25. SVCB_MANDATORY: "mandatory",
  26. SVCB_ALPN: "alpn",
  27. SVCB_NO_DEFAULT_ALPN: "no-default-alpn",
  28. SVCB_PORT: "port",
  29. SVCB_IPV4HINT: "ipv4hint",
  30. SVCB_ECHCONFIG: "echconfig",
  31. SVCB_IPV6HINT: "ipv6hint",
  32. }
  33. var svcbStringToKeyMap = reverseSVCBKeyMap(svcbKeyToStringMap)
  34. func reverseSVCBKeyMap(m map[SVCBKey]string) map[string]SVCBKey {
  35. n := make(map[string]SVCBKey, len(m))
  36. for u, s := range m {
  37. n[s] = u
  38. }
  39. return n
  40. }
  41. // String takes the numerical code of an SVCB key and returns its name.
  42. // Returns an empty string for reserved keys.
  43. // Accepts unassigned keys as well as experimental/private keys.
  44. func (key SVCBKey) String() string {
  45. if x := svcbKeyToStringMap[key]; x != "" {
  46. return x
  47. }
  48. if key == svcb_RESERVED {
  49. return ""
  50. }
  51. return "key" + strconv.FormatUint(uint64(key), 10)
  52. }
  53. // svcbStringToKey returns the numerical code of an SVCB key.
  54. // Returns svcb_RESERVED for reserved/invalid keys.
  55. // Accepts unassigned keys as well as experimental/private keys.
  56. func svcbStringToKey(s string) SVCBKey {
  57. if strings.HasPrefix(s, "key") {
  58. a, err := strconv.ParseUint(s[3:], 10, 16)
  59. // no leading zeros
  60. // key shouldn't be registered
  61. if err != nil || a == 65535 || s[3] == '0' || svcbKeyToStringMap[SVCBKey(a)] != "" {
  62. return svcb_RESERVED
  63. }
  64. return SVCBKey(a)
  65. }
  66. if key, ok := svcbStringToKeyMap[s]; ok {
  67. return key
  68. }
  69. return svcb_RESERVED
  70. }
  71. func (rr *SVCB) parse(c *zlexer, o string) *ParseError {
  72. l, _ := c.Next()
  73. i, e := strconv.ParseUint(l.token, 10, 16)
  74. if e != nil || l.err {
  75. return &ParseError{l.token, "bad SVCB priority", l}
  76. }
  77. rr.Priority = uint16(i)
  78. c.Next() // zBlank
  79. l, _ = c.Next() // zString
  80. rr.Target = l.token
  81. name, nameOk := toAbsoluteName(l.token, o)
  82. if l.err || !nameOk {
  83. return &ParseError{l.token, "bad SVCB Target", l}
  84. }
  85. rr.Target = name
  86. // Values (if any)
  87. l, _ = c.Next()
  88. var xs []SVCBKeyValue
  89. // Helps require whitespace between pairs.
  90. // Prevents key1000="a"key1001=...
  91. canHaveNextKey := true
  92. for l.value != zNewline && l.value != zEOF {
  93. switch l.value {
  94. case zString:
  95. if !canHaveNextKey {
  96. // The key we can now read was probably meant to be
  97. // a part of the last value.
  98. return &ParseError{l.token, "bad SVCB value quotation", l}
  99. }
  100. // In key=value pairs, value does not have to be quoted unless value
  101. // contains whitespace. And keys don't need to have values.
  102. // Similarly, keys with an equality signs after them don't need values.
  103. // l.token includes at least up to the first equality sign.
  104. idx := strings.IndexByte(l.token, '=')
  105. var key, value string
  106. if idx < 0 {
  107. // Key with no value and no equality sign
  108. key = l.token
  109. } else if idx == 0 {
  110. return &ParseError{l.token, "bad SVCB key", l}
  111. } else {
  112. key, value = l.token[:idx], l.token[idx+1:]
  113. if value == "" {
  114. // We have a key and an equality sign. Maybe we have nothing
  115. // after "=" or we have a double quote.
  116. l, _ = c.Next()
  117. if l.value == zQuote {
  118. // Only needed when value ends with double quotes.
  119. // Any value starting with zQuote ends with it.
  120. canHaveNextKey = false
  121. l, _ = c.Next()
  122. switch l.value {
  123. case zString:
  124. // We have a value in double quotes.
  125. value = l.token
  126. l, _ = c.Next()
  127. if l.value != zQuote {
  128. return &ParseError{l.token, "SVCB unterminated value", l}
  129. }
  130. case zQuote:
  131. // There's nothing in double quotes.
  132. default:
  133. return &ParseError{l.token, "bad SVCB value", l}
  134. }
  135. }
  136. }
  137. }
  138. kv := makeSVCBKeyValue(svcbStringToKey(key))
  139. if kv == nil {
  140. return &ParseError{l.token, "bad SVCB key", l}
  141. }
  142. if err := kv.parse(value); err != nil {
  143. return &ParseError{l.token, err.Error(), l}
  144. }
  145. xs = append(xs, kv)
  146. case zQuote:
  147. return &ParseError{l.token, "SVCB key can't contain double quotes", l}
  148. case zBlank:
  149. canHaveNextKey = true
  150. default:
  151. return &ParseError{l.token, "bad SVCB values", l}
  152. }
  153. l, _ = c.Next()
  154. }
  155. rr.Value = xs
  156. if rr.Priority == 0 && len(xs) > 0 {
  157. return &ParseError{l.token, "SVCB aliasform can't have values", l}
  158. }
  159. return nil
  160. }
  161. // makeSVCBKeyValue returns an SVCBKeyValue struct with the key or nil for reserved keys.
  162. func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
  163. switch key {
  164. case SVCB_MANDATORY:
  165. return new(SVCBMandatory)
  166. case SVCB_ALPN:
  167. return new(SVCBAlpn)
  168. case SVCB_NO_DEFAULT_ALPN:
  169. return new(SVCBNoDefaultAlpn)
  170. case SVCB_PORT:
  171. return new(SVCBPort)
  172. case SVCB_IPV4HINT:
  173. return new(SVCBIPv4Hint)
  174. case SVCB_ECHCONFIG:
  175. return new(SVCBECHConfig)
  176. case SVCB_IPV6HINT:
  177. return new(SVCBIPv6Hint)
  178. case svcb_RESERVED:
  179. return nil
  180. default:
  181. e := new(SVCBLocal)
  182. e.KeyCode = key
  183. return e
  184. }
  185. }
  186. // SVCB RR. See RFC xxxx (https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-01).
  187. type SVCB struct {
  188. Hdr RR_Header
  189. Priority uint16
  190. Target string `dns:"domain-name"`
  191. Value []SVCBKeyValue `dns:"pairs"` // Value must be empty if Priority is zero.
  192. }
  193. // HTTPS RR. Everything valid for SVCB applies to HTTPS as well.
  194. // Except that the HTTPS record is intended for use with the HTTP and HTTPS protocols.
  195. type HTTPS struct {
  196. SVCB
  197. }
  198. func (rr *HTTPS) String() string {
  199. return rr.SVCB.String()
  200. }
  201. func (rr *HTTPS) parse(c *zlexer, o string) *ParseError {
  202. return rr.SVCB.parse(c, o)
  203. }
  204. // SVCBKeyValue defines a key=value pair for the SVCB RR type.
  205. // An SVCB RR can have multiple SVCBKeyValues appended to it.
  206. type SVCBKeyValue interface {
  207. Key() SVCBKey // Key returns the numerical key code.
  208. pack() ([]byte, error) // pack returns the encoded value.
  209. unpack([]byte) error // unpack sets the value.
  210. String() string // String returns the string representation of the value.
  211. parse(string) error // parse sets the value to the given string representation of the value.
  212. copy() SVCBKeyValue // copy returns a deep-copy of the pair.
  213. len() int // len returns the length of value in the wire format.
  214. }
  215. // SVCBMandatory pair adds to required keys that must be interpreted for the RR
  216. // to be functional.
  217. // Basic use pattern for creating a mandatory option:
  218. //
  219. // s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
  220. // e := new(dns.SVCBMandatory)
  221. // e.Code = []uint16{65403}
  222. // s.Value = append(s.Value, e)
  223. type SVCBMandatory struct {
  224. Code []SVCBKey // Must not include mandatory
  225. }
  226. func (*SVCBMandatory) Key() SVCBKey { return SVCB_MANDATORY }
  227. func (s *SVCBMandatory) String() string {
  228. str := make([]string, len(s.Code))
  229. for i, e := range s.Code {
  230. str[i] = e.String()
  231. }
  232. return strings.Join(str, ",")
  233. }
  234. func (s *SVCBMandatory) pack() ([]byte, error) {
  235. codes := append([]SVCBKey(nil), s.Code...)
  236. sort.Slice(codes, func(i, j int) bool {
  237. return codes[i] < codes[j]
  238. })
  239. b := make([]byte, 2*len(codes))
  240. for i, e := range codes {
  241. binary.BigEndian.PutUint16(b[2*i:], uint16(e))
  242. }
  243. return b, nil
  244. }
  245. func (s *SVCBMandatory) unpack(b []byte) error {
  246. if len(b)%2 != 0 {
  247. return errors.New("dns: svcbmandatory: value length is not a multiple of 2")
  248. }
  249. codes := make([]SVCBKey, 0, len(b)/2)
  250. for i := 0; i < len(b); i += 2 {
  251. // We assume strictly increasing order.
  252. codes = append(codes, SVCBKey(binary.BigEndian.Uint16(b[i:])))
  253. }
  254. s.Code = codes
  255. return nil
  256. }
  257. func (s *SVCBMandatory) parse(b string) error {
  258. str := strings.Split(b, ",")
  259. codes := make([]SVCBKey, 0, len(str))
  260. for _, e := range str {
  261. codes = append(codes, svcbStringToKey(e))
  262. }
  263. s.Code = codes
  264. return nil
  265. }
  266. func (s *SVCBMandatory) len() int {
  267. return 2 * len(s.Code)
  268. }
  269. func (s *SVCBMandatory) copy() SVCBKeyValue {
  270. return &SVCBMandatory{
  271. append([]SVCBKey(nil), s.Code...),
  272. }
  273. }
  274. // SVCBAlpn pair is used to list supported connection protocols.
  275. // Protocol ids can be found at:
  276. // https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
  277. // Basic use pattern for creating an alpn option:
  278. //
  279. // h := new(dns.HTTPS)
  280. // h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
  281. // e := new(dns.SVCBAlpn)
  282. // e.Alpn = []string{"h2", "http/1.1"}
  283. // h.Value = append(o.Value, e)
  284. type SVCBAlpn struct {
  285. Alpn []string
  286. }
  287. func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN }
  288. func (s *SVCBAlpn) String() string { return strings.Join(s.Alpn, ",") }
  289. func (s *SVCBAlpn) pack() ([]byte, error) {
  290. // Liberally estimate the size of an alpn as 10 octets
  291. b := make([]byte, 0, 10*len(s.Alpn))
  292. for _, e := range s.Alpn {
  293. if e == "" {
  294. return nil, errors.New("dns: svcbalpn: empty alpn-id")
  295. }
  296. if len(e) > 255 {
  297. return nil, errors.New("dns: svcbalpn: alpn-id too long")
  298. }
  299. b = append(b, byte(len(e)))
  300. b = append(b, e...)
  301. }
  302. return b, nil
  303. }
  304. func (s *SVCBAlpn) unpack(b []byte) error {
  305. // Estimate the size of the smallest alpn as 4 bytes
  306. alpn := make([]string, 0, len(b)/4)
  307. for i := 0; i < len(b); {
  308. length := int(b[i])
  309. i++
  310. if i+length > len(b) {
  311. return errors.New("dns: svcbalpn: alpn array overflowing")
  312. }
  313. alpn = append(alpn, string(b[i:i+length]))
  314. i += length
  315. }
  316. s.Alpn = alpn
  317. return nil
  318. }
  319. func (s *SVCBAlpn) parse(b string) error {
  320. s.Alpn = strings.Split(b, ",")
  321. return nil
  322. }
  323. func (s *SVCBAlpn) len() int {
  324. var l int
  325. for _, e := range s.Alpn {
  326. l += 1 + len(e)
  327. }
  328. return l
  329. }
  330. func (s *SVCBAlpn) copy() SVCBKeyValue {
  331. return &SVCBAlpn{
  332. append([]string(nil), s.Alpn...),
  333. }
  334. }
  335. // SVCBNoDefaultAlpn pair signifies no support for default connection protocols.
  336. // Basic use pattern for creating a no-default-alpn option:
  337. //
  338. // s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
  339. // e := new(dns.SVCBNoDefaultAlpn)
  340. // s.Value = append(s.Value, e)
  341. type SVCBNoDefaultAlpn struct{}
  342. func (*SVCBNoDefaultAlpn) Key() SVCBKey { return SVCB_NO_DEFAULT_ALPN }
  343. func (*SVCBNoDefaultAlpn) copy() SVCBKeyValue { return &SVCBNoDefaultAlpn{} }
  344. func (*SVCBNoDefaultAlpn) pack() ([]byte, error) { return []byte{}, nil }
  345. func (*SVCBNoDefaultAlpn) String() string { return "" }
  346. func (*SVCBNoDefaultAlpn) len() int { return 0 }
  347. func (*SVCBNoDefaultAlpn) unpack(b []byte) error {
  348. if len(b) != 0 {
  349. return errors.New("dns: svcbnodefaultalpn: no_default_alpn must have no value")
  350. }
  351. return nil
  352. }
  353. func (*SVCBNoDefaultAlpn) parse(b string) error {
  354. if b != "" {
  355. return errors.New("dns: svcbnodefaultalpn: no_default_alpn must have no value")
  356. }
  357. return nil
  358. }
  359. // SVCBPort pair defines the port for connection.
  360. // Basic use pattern for creating a port option:
  361. //
  362. // s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
  363. // e := new(dns.SVCBPort)
  364. // e.Port = 80
  365. // s.Value = append(s.Value, e)
  366. type SVCBPort struct {
  367. Port uint16
  368. }
  369. func (*SVCBPort) Key() SVCBKey { return SVCB_PORT }
  370. func (*SVCBPort) len() int { return 2 }
  371. func (s *SVCBPort) String() string { return strconv.FormatUint(uint64(s.Port), 10) }
  372. func (s *SVCBPort) copy() SVCBKeyValue { return &SVCBPort{s.Port} }
  373. func (s *SVCBPort) unpack(b []byte) error {
  374. if len(b) != 2 {
  375. return errors.New("dns: svcbport: port length is not exactly 2 octets")
  376. }
  377. s.Port = binary.BigEndian.Uint16(b)
  378. return nil
  379. }
  380. func (s *SVCBPort) pack() ([]byte, error) {
  381. b := make([]byte, 2)
  382. binary.BigEndian.PutUint16(b, s.Port)
  383. return b, nil
  384. }
  385. func (s *SVCBPort) parse(b string) error {
  386. port, err := strconv.ParseUint(b, 10, 16)
  387. if err != nil {
  388. return errors.New("dns: svcbport: port out of range")
  389. }
  390. s.Port = uint16(port)
  391. return nil
  392. }
  393. // SVCBIPv4Hint pair suggests an IPv4 address which may be used to open connections
  394. // if A and AAAA record responses for SVCB's Target domain haven't been received.
  395. // In that case, optionally, A and AAAA requests can be made, after which the connection
  396. // to the hinted IP address may be terminated and a new connection may be opened.
  397. // Basic use pattern for creating an ipv4hint option:
  398. //
  399. // h := new(dns.HTTPS)
  400. // h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
  401. // e := new(dns.SVCBIPv4Hint)
  402. // e.Hint = []net.IP{net.IPv4(1,1,1,1).To4()}
  403. //
  404. // Or
  405. //
  406. // e.Hint = []net.IP{net.ParseIP("1.1.1.1").To4()}
  407. // h.Value = append(h.Value, e)
  408. type SVCBIPv4Hint struct {
  409. Hint []net.IP
  410. }
  411. func (*SVCBIPv4Hint) Key() SVCBKey { return SVCB_IPV4HINT }
  412. func (s *SVCBIPv4Hint) len() int { return 4 * len(s.Hint) }
  413. func (s *SVCBIPv4Hint) pack() ([]byte, error) {
  414. b := make([]byte, 0, 4*len(s.Hint))
  415. for _, e := range s.Hint {
  416. x := e.To4()
  417. if x == nil {
  418. return nil, errors.New("dns: svcbipv4hint: expected ipv4, hint is ipv6")
  419. }
  420. b = append(b, x...)
  421. }
  422. return b, nil
  423. }
  424. func (s *SVCBIPv4Hint) unpack(b []byte) error {
  425. if len(b) == 0 || len(b)%4 != 0 {
  426. return errors.New("dns: svcbipv4hint: ipv4 address byte array length is not a multiple of 4")
  427. }
  428. x := make([]net.IP, 0, len(b)/4)
  429. for i := 0; i < len(b); i += 4 {
  430. x = append(x, net.IP(b[i:i+4]))
  431. }
  432. s.Hint = x
  433. return nil
  434. }
  435. func (s *SVCBIPv4Hint) String() string {
  436. str := make([]string, len(s.Hint))
  437. for i, e := range s.Hint {
  438. x := e.To4()
  439. if x == nil {
  440. return "<nil>"
  441. }
  442. str[i] = x.String()
  443. }
  444. return strings.Join(str, ",")
  445. }
  446. func (s *SVCBIPv4Hint) parse(b string) error {
  447. if strings.Contains(b, ":") {
  448. return errors.New("dns: svcbipv4hint: expected ipv4, got ipv6")
  449. }
  450. str := strings.Split(b, ",")
  451. dst := make([]net.IP, len(str))
  452. for i, e := range str {
  453. ip := net.ParseIP(e).To4()
  454. if ip == nil {
  455. return errors.New("dns: svcbipv4hint: bad ip")
  456. }
  457. dst[i] = ip
  458. }
  459. s.Hint = dst
  460. return nil
  461. }
  462. func (s *SVCBIPv4Hint) copy() SVCBKeyValue {
  463. hint := make([]net.IP, len(s.Hint))
  464. for i, ip := range s.Hint {
  465. hint[i] = copyIP(ip)
  466. }
  467. return &SVCBIPv4Hint{
  468. Hint: hint,
  469. }
  470. }
  471. // SVCBECHConfig pair contains the ECHConfig structure defined in draft-ietf-tls-esni [RFC xxxx].
  472. // Basic use pattern for creating an echconfig option:
  473. //
  474. // h := new(dns.HTTPS)
  475. // h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
  476. // e := new(dns.SVCBECHConfig)
  477. // e.ECH = []byte{0xfe, 0x08, ...}
  478. // h.Value = append(h.Value, e)
  479. type SVCBECHConfig struct {
  480. ECH []byte
  481. }
  482. func (*SVCBECHConfig) Key() SVCBKey { return SVCB_ECHCONFIG }
  483. func (s *SVCBECHConfig) String() string { return toBase64(s.ECH) }
  484. func (s *SVCBECHConfig) len() int { return len(s.ECH) }
  485. func (s *SVCBECHConfig) pack() ([]byte, error) {
  486. return append([]byte(nil), s.ECH...), nil
  487. }
  488. func (s *SVCBECHConfig) copy() SVCBKeyValue {
  489. return &SVCBECHConfig{
  490. append([]byte(nil), s.ECH...),
  491. }
  492. }
  493. func (s *SVCBECHConfig) unpack(b []byte) error {
  494. s.ECH = append([]byte(nil), b...)
  495. return nil
  496. }
  497. func (s *SVCBECHConfig) parse(b string) error {
  498. x, err := fromBase64([]byte(b))
  499. if err != nil {
  500. return errors.New("dns: svcbechconfig: bad base64 echconfig")
  501. }
  502. s.ECH = x
  503. return nil
  504. }
  505. // SVCBIPv6Hint pair suggests an IPv6 address which may be used to open connections
  506. // if A and AAAA record responses for SVCB's Target domain haven't been received.
  507. // In that case, optionally, A and AAAA requests can be made, after which the
  508. // connection to the hinted IP address may be terminated and a new connection may be opened.
  509. // Basic use pattern for creating an ipv6hint option:
  510. //
  511. // h := new(dns.HTTPS)
  512. // h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
  513. // e := new(dns.SVCBIPv6Hint)
  514. // e.Hint = []net.IP{net.ParseIP("2001:db8::1")}
  515. // h.Value = append(h.Value, e)
  516. type SVCBIPv6Hint struct {
  517. Hint []net.IP
  518. }
  519. func (*SVCBIPv6Hint) Key() SVCBKey { return SVCB_IPV6HINT }
  520. func (s *SVCBIPv6Hint) len() int { return 16 * len(s.Hint) }
  521. func (s *SVCBIPv6Hint) pack() ([]byte, error) {
  522. b := make([]byte, 0, 16*len(s.Hint))
  523. for _, e := range s.Hint {
  524. if len(e) != net.IPv6len || e.To4() != nil {
  525. return nil, errors.New("dns: svcbipv6hint: expected ipv6, hint is ipv4")
  526. }
  527. b = append(b, e...)
  528. }
  529. return b, nil
  530. }
  531. func (s *SVCBIPv6Hint) unpack(b []byte) error {
  532. if len(b) == 0 || len(b)%16 != 0 {
  533. return errors.New("dns: svcbipv6hint: ipv6 address byte array length not a multiple of 16")
  534. }
  535. x := make([]net.IP, 0, len(b)/16)
  536. for i := 0; i < len(b); i += 16 {
  537. ip := net.IP(b[i : i+16])
  538. if ip.To4() != nil {
  539. return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4")
  540. }
  541. x = append(x, ip)
  542. }
  543. s.Hint = x
  544. return nil
  545. }
  546. func (s *SVCBIPv6Hint) String() string {
  547. str := make([]string, len(s.Hint))
  548. for i, e := range s.Hint {
  549. if x := e.To4(); x != nil {
  550. return "<nil>"
  551. }
  552. str[i] = e.String()
  553. }
  554. return strings.Join(str, ",")
  555. }
  556. func (s *SVCBIPv6Hint) parse(b string) error {
  557. if strings.Contains(b, ".") {
  558. return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4")
  559. }
  560. str := strings.Split(b, ",")
  561. dst := make([]net.IP, len(str))
  562. for i, e := range str {
  563. ip := net.ParseIP(e)
  564. if ip == nil {
  565. return errors.New("dns: svcbipv6hint: bad ip")
  566. }
  567. dst[i] = ip
  568. }
  569. s.Hint = dst
  570. return nil
  571. }
  572. func (s *SVCBIPv6Hint) copy() SVCBKeyValue {
  573. hint := make([]net.IP, len(s.Hint))
  574. for i, ip := range s.Hint {
  575. hint[i] = copyIP(ip)
  576. }
  577. return &SVCBIPv6Hint{
  578. Hint: hint,
  579. }
  580. }
  581. // SVCBLocal pair is intended for experimental/private use. The key is recommended
  582. // to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER].
  583. // Basic use pattern for creating a keyNNNNN option:
  584. //
  585. // h := new(dns.HTTPS)
  586. // h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
  587. // e := new(dns.SVCBLocal)
  588. // e.KeyCode = 65400
  589. // e.Data = []byte("abc")
  590. // h.Value = append(h.Value, e)
  591. type SVCBLocal struct {
  592. KeyCode SVCBKey // Never 65535 or any assigned keys.
  593. Data []byte // All byte sequences are allowed.
  594. }
  595. func (s *SVCBLocal) Key() SVCBKey { return s.KeyCode }
  596. func (s *SVCBLocal) pack() ([]byte, error) { return append([]byte(nil), s.Data...), nil }
  597. func (s *SVCBLocal) len() int { return len(s.Data) }
  598. func (s *SVCBLocal) unpack(b []byte) error {
  599. s.Data = append([]byte(nil), b...)
  600. return nil
  601. }
  602. func (s *SVCBLocal) String() string {
  603. var str strings.Builder
  604. str.Grow(4 * len(s.Data))
  605. for _, e := range s.Data {
  606. if ' ' <= e && e <= '~' {
  607. switch e {
  608. case '"', ';', ' ', '\\':
  609. str.WriteByte('\\')
  610. str.WriteByte(e)
  611. default:
  612. str.WriteByte(e)
  613. }
  614. } else {
  615. str.WriteString(escapeByte(e))
  616. }
  617. }
  618. return str.String()
  619. }
  620. func (s *SVCBLocal) parse(b string) error {
  621. data := make([]byte, 0, len(b))
  622. for i := 0; i < len(b); {
  623. if b[i] != '\\' {
  624. data = append(data, b[i])
  625. i++
  626. continue
  627. }
  628. if i+1 == len(b) {
  629. return errors.New("dns: svcblocal: svcb private/experimental key escape unterminated")
  630. }
  631. if isDigit(b[i+1]) {
  632. if i+3 < len(b) && isDigit(b[i+2]) && isDigit(b[i+3]) {
  633. a, err := strconv.ParseUint(b[i+1:i+4], 10, 8)
  634. if err == nil {
  635. i += 4
  636. data = append(data, byte(a))
  637. continue
  638. }
  639. }
  640. return errors.New("dns: svcblocal: svcb private/experimental key bad escaped octet")
  641. } else {
  642. data = append(data, b[i+1])
  643. i += 2
  644. }
  645. }
  646. s.Data = data
  647. return nil
  648. }
  649. func (s *SVCBLocal) copy() SVCBKeyValue {
  650. return &SVCBLocal{s.KeyCode,
  651. append([]byte(nil), s.Data...),
  652. }
  653. }
  654. func (rr *SVCB) String() string {
  655. s := rr.Hdr.String() +
  656. strconv.Itoa(int(rr.Priority)) + " " +
  657. sprintName(rr.Target)
  658. for _, e := range rr.Value {
  659. s += " " + e.Key().String() + "=\"" + e.String() + "\""
  660. }
  661. return s
  662. }
  663. // areSVCBPairArraysEqual checks if SVCBKeyValue arrays are equal after sorting their
  664. // copies. arrA and arrB have equal lengths, otherwise zduplicate.go wouldn't call this function.
  665. func areSVCBPairArraysEqual(a []SVCBKeyValue, b []SVCBKeyValue) bool {
  666. a = append([]SVCBKeyValue(nil), a...)
  667. b = append([]SVCBKeyValue(nil), b...)
  668. sort.Slice(a, func(i, j int) bool { return a[i].Key() < a[j].Key() })
  669. sort.Slice(b, func(i, j int) bool { return b[i].Key() < b[j].Key() })
  670. for i, e := range a {
  671. if e.Key() != b[i].Key() {
  672. return false
  673. }
  674. b1, err1 := e.pack()
  675. b2, err2 := b[i].pack()
  676. if err1 != nil || err2 != nil || !bytes.Equal(b1, b2) {
  677. return false
  678. }
  679. }
  680. return true
  681. }