1 package dns
2
3 import (
4 "encoding/binary"
5 "encoding/hex"
6 "errors"
7 "fmt"
8 "net"
9 "strconv"
10 )
11
12
13 const (
14 EDNS0LLQ = 0x1
15 EDNS0UL = 0x2
16 EDNS0NSID = 0x3
17 EDNS0ESU = 0x4
18 EDNS0DAU = 0x5
19 EDNS0DHU = 0x6
20 EDNS0N3U = 0x7
21 EDNS0SUBNET = 0x8
22 EDNS0EXPIRE = 0x9
23 EDNS0COOKIE = 0xa
24 EDNS0TCPKEEPALIVE = 0xb
25 EDNS0PADDING = 0xc
26 EDNS0EDE = 0xf
27 EDNS0LOCALSTART = 0xFDE9
28 EDNS0LOCALEND = 0xFFFE
29 _DO = 1 << 15
30 )
31
32
33 func makeDataOpt(code uint16) EDNS0 {
34
35 switch code {
36 case EDNS0LLQ:
37 return new(EDNS0_LLQ)
38 case EDNS0UL:
39 return new(EDNS0_UL)
40 case EDNS0NSID:
41 return new(EDNS0_NSID)
42 case EDNS0DAU:
43 return new(EDNS0_DAU)
44 case EDNS0DHU:
45 return new(EDNS0_DHU)
46 case EDNS0N3U:
47 return new(EDNS0_N3U)
48 case EDNS0SUBNET:
49 return new(EDNS0_SUBNET)
50 case EDNS0EXPIRE:
51 return new(EDNS0_EXPIRE)
52 case EDNS0COOKIE:
53 return new(EDNS0_COOKIE)
54 case EDNS0TCPKEEPALIVE:
55 return new(EDNS0_TCP_KEEPALIVE)
56 case EDNS0PADDING:
57 return new(EDNS0_PADDING)
58 case EDNS0EDE:
59 return new(EDNS0_EDE)
60 case EDNS0ESU:
61 return &EDNS0_ESU{Code: EDNS0ESU}
62 default:
63 e := new(EDNS0_LOCAL)
64 e.Code = code
65 return e
66 }
67 }
68
69
70
71 type OPT struct {
72 Hdr RR_Header
73 Option []EDNS0 `dns:"opt"`
74 }
75
76 func (rr *OPT) String() string {
77 s := "\n;; OPT PSEUDOSECTION:\n; EDNS: version " + strconv.Itoa(int(rr.Version())) + "; "
78 if rr.Do() {
79 s += "flags: do; "
80 } else {
81 s += "flags:; "
82 }
83 if rr.Hdr.Ttl&0x7FFF != 0 {
84 s += fmt.Sprintf("MBZ: 0x%04x, ", rr.Hdr.Ttl&0x7FFF)
85 }
86 s += "udp: " + strconv.Itoa(int(rr.UDPSize()))
87
88 for _, o := range rr.Option {
89 switch o.(type) {
90 case *EDNS0_NSID:
91 s += "\n; NSID: " + o.String()
92 h, e := o.pack()
93 var r string
94 if e == nil {
95 for _, c := range h {
96 r += "(" + string(c) + ")"
97 }
98 s += " " + r
99 }
100 case *EDNS0_SUBNET:
101 s += "\n; SUBNET: " + o.String()
102 case *EDNS0_COOKIE:
103 s += "\n; COOKIE: " + o.String()
104 case *EDNS0_EXPIRE:
105 s += "\n; EXPIRE: " + o.String()
106 case *EDNS0_TCP_KEEPALIVE:
107 s += "\n; KEEPALIVE: " + o.String()
108 case *EDNS0_UL:
109 s += "\n; UPDATE LEASE: " + o.String()
110 case *EDNS0_LLQ:
111 s += "\n; LONG LIVED QUERIES: " + o.String()
112 case *EDNS0_DAU:
113 s += "\n; DNSSEC ALGORITHM UNDERSTOOD: " + o.String()
114 case *EDNS0_DHU:
115 s += "\n; DS HASH UNDERSTOOD: " + o.String()
116 case *EDNS0_N3U:
117 s += "\n; NSEC3 HASH UNDERSTOOD: " + o.String()
118 case *EDNS0_LOCAL:
119 s += "\n; LOCAL OPT: " + o.String()
120 case *EDNS0_PADDING:
121 s += "\n; PADDING: " + o.String()
122 case *EDNS0_EDE:
123 s += "\n; EDE: " + o.String()
124 case *EDNS0_ESU:
125 s += "\n; ESU: " + o.String()
126 }
127 }
128 return s
129 }
130
131 func (rr *OPT) len(off int, compression map[string]struct{}) int {
132 l := rr.Hdr.len(off, compression)
133 for _, o := range rr.Option {
134 l += 4
135 lo, _ := o.pack()
136 l += len(lo)
137 }
138 return l
139 }
140
141 func (*OPT) parse(c *zlexer, origin string) *ParseError {
142 return &ParseError{err: "OPT records do not have a presentation format"}
143 }
144
145 func (rr *OPT) isDuplicate(r2 RR) bool { return false }
146
147
148
149
150 func (rr *OPT) Version() uint8 {
151 return uint8(rr.Hdr.Ttl & 0x00FF0000 >> 16)
152 }
153
154
155 func (rr *OPT) SetVersion(v uint8) {
156 rr.Hdr.Ttl = rr.Hdr.Ttl&0xFF00FFFF | uint32(v)<<16
157 }
158
159
160 func (rr *OPT) ExtendedRcode() int {
161 return int(rr.Hdr.Ttl&0xFF000000>>24) << 4
162 }
163
164
165
166
167 func (rr *OPT) SetExtendedRcode(v uint16) {
168 rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | uint32(v>>4)<<24
169 }
170
171
172 func (rr *OPT) UDPSize() uint16 {
173 return rr.Hdr.Class
174 }
175
176
177 func (rr *OPT) SetUDPSize(size uint16) {
178 rr.Hdr.Class = size
179 }
180
181
182 func (rr *OPT) Do() bool {
183 return rr.Hdr.Ttl&_DO == _DO
184 }
185
186
187
188
189 func (rr *OPT) SetDo(do ...bool) {
190 if len(do) == 1 {
191 if do[0] {
192 rr.Hdr.Ttl |= _DO
193 } else {
194 rr.Hdr.Ttl &^= _DO
195 }
196 } else {
197 rr.Hdr.Ttl |= _DO
198 }
199 }
200
201
202 func (rr *OPT) Z() uint16 {
203 return uint16(rr.Hdr.Ttl & 0x7FFF)
204 }
205
206
207 func (rr *OPT) SetZ(z uint16) {
208 rr.Hdr.Ttl = rr.Hdr.Ttl&^0x7FFF | uint32(z&0x7FFF)
209 }
210
211
212 type EDNS0 interface {
213
214 Option() uint16
215
216 pack() ([]byte, error)
217
218
219 unpack([]byte) error
220
221 String() string
222
223 copy() EDNS0
224 }
225
226
227
228
229
230
231
232
233
234
235
236
237
238 type EDNS0_NSID struct {
239 Code uint16
240 Nsid string
241 }
242
243 func (e *EDNS0_NSID) pack() ([]byte, error) {
244 h, err := hex.DecodeString(e.Nsid)
245 if err != nil {
246 return nil, err
247 }
248 return h, nil
249 }
250
251
252 func (e *EDNS0_NSID) Option() uint16 { return EDNS0NSID }
253 func (e *EDNS0_NSID) unpack(b []byte) error { e.Nsid = hex.EncodeToString(b); return nil }
254 func (e *EDNS0_NSID) String() string { return e.Nsid }
255 func (e *EDNS0_NSID) copy() EDNS0 { return &EDNS0_NSID{e.Code, e.Nsid} }
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277 type EDNS0_SUBNET struct {
278 Code uint16
279 Family uint16
280 SourceNetmask uint8
281 SourceScope uint8
282 Address net.IP
283 }
284
285
286 func (e *EDNS0_SUBNET) Option() uint16 { return EDNS0SUBNET }
287
288 func (e *EDNS0_SUBNET) pack() ([]byte, error) {
289 b := make([]byte, 4)
290 binary.BigEndian.PutUint16(b[0:], e.Family)
291 b[2] = e.SourceNetmask
292 b[3] = e.SourceScope
293 switch e.Family {
294 case 0:
295
296
297 if e.SourceNetmask != 0 {
298 return nil, errors.New("dns: bad address family")
299 }
300 case 1:
301 if e.SourceNetmask > net.IPv4len*8 {
302 return nil, errors.New("dns: bad netmask")
303 }
304 if len(e.Address.To4()) != net.IPv4len {
305 return nil, errors.New("dns: bad address")
306 }
307 ip := e.Address.To4().Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv4len*8))
308 needLength := (e.SourceNetmask + 8 - 1) / 8
309 b = append(b, ip[:needLength]...)
310 case 2:
311 if e.SourceNetmask > net.IPv6len*8 {
312 return nil, errors.New("dns: bad netmask")
313 }
314 if len(e.Address) != net.IPv6len {
315 return nil, errors.New("dns: bad address")
316 }
317 ip := e.Address.Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv6len*8))
318 needLength := (e.SourceNetmask + 8 - 1) / 8
319 b = append(b, ip[:needLength]...)
320 default:
321 return nil, errors.New("dns: bad address family")
322 }
323 return b, nil
324 }
325
326 func (e *EDNS0_SUBNET) unpack(b []byte) error {
327 if len(b) < 4 {
328 return ErrBuf
329 }
330 e.Family = binary.BigEndian.Uint16(b)
331 e.SourceNetmask = b[2]
332 e.SourceScope = b[3]
333 switch e.Family {
334 case 0:
335
336
337 if e.SourceNetmask != 0 {
338 return errors.New("dns: bad address family")
339 }
340 e.Address = net.IPv4(0, 0, 0, 0)
341 case 1:
342 if e.SourceNetmask > net.IPv4len*8 || e.SourceScope > net.IPv4len*8 {
343 return errors.New("dns: bad netmask")
344 }
345 addr := make(net.IP, net.IPv4len)
346 copy(addr, b[4:])
347 e.Address = addr.To16()
348 case 2:
349 if e.SourceNetmask > net.IPv6len*8 || e.SourceScope > net.IPv6len*8 {
350 return errors.New("dns: bad netmask")
351 }
352 addr := make(net.IP, net.IPv6len)
353 copy(addr, b[4:])
354 e.Address = addr
355 default:
356 return errors.New("dns: bad address family")
357 }
358 return nil
359 }
360
361 func (e *EDNS0_SUBNET) String() (s string) {
362 if e.Address == nil {
363 s = "<nil>"
364 } else if e.Address.To4() != nil {
365 s = e.Address.String()
366 } else {
367 s = "[" + e.Address.String() + "]"
368 }
369 s += "/" + strconv.Itoa(int(e.SourceNetmask)) + "/" + strconv.Itoa(int(e.SourceScope))
370 return
371 }
372
373 func (e *EDNS0_SUBNET) copy() EDNS0 {
374 return &EDNS0_SUBNET{
375 e.Code,
376 e.Family,
377 e.SourceNetmask,
378 e.SourceScope,
379 e.Address,
380 }
381 }
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401 type EDNS0_COOKIE struct {
402 Code uint16
403 Cookie string
404 }
405
406 func (e *EDNS0_COOKIE) pack() ([]byte, error) {
407 h, err := hex.DecodeString(e.Cookie)
408 if err != nil {
409 return nil, err
410 }
411 return h, nil
412 }
413
414
415 func (e *EDNS0_COOKIE) Option() uint16 { return EDNS0COOKIE }
416 func (e *EDNS0_COOKIE) unpack(b []byte) error { e.Cookie = hex.EncodeToString(b); return nil }
417 func (e *EDNS0_COOKIE) String() string { return e.Cookie }
418 func (e *EDNS0_COOKIE) copy() EDNS0 { return &EDNS0_COOKIE{e.Code, e.Cookie} }
419
420
421
422
423
424
425
426
427
428
429
430
431
432 type EDNS0_UL struct {
433 Code uint16
434 Lease uint32
435 KeyLease uint32
436 }
437
438
439 func (e *EDNS0_UL) Option() uint16 { return EDNS0UL }
440 func (e *EDNS0_UL) String() string { return fmt.Sprintf("%d %d", e.Lease, e.KeyLease) }
441 func (e *EDNS0_UL) copy() EDNS0 { return &EDNS0_UL{e.Code, e.Lease, e.KeyLease} }
442
443
444 func (e *EDNS0_UL) pack() ([]byte, error) {
445 var b []byte
446 if e.KeyLease == 0 {
447 b = make([]byte, 4)
448 } else {
449 b = make([]byte, 8)
450 binary.BigEndian.PutUint32(b[4:], e.KeyLease)
451 }
452 binary.BigEndian.PutUint32(b, e.Lease)
453 return b, nil
454 }
455
456 func (e *EDNS0_UL) unpack(b []byte) error {
457 switch len(b) {
458 case 4:
459 e.KeyLease = 0
460 case 8:
461 e.KeyLease = binary.BigEndian.Uint32(b[4:])
462 default:
463 return ErrBuf
464 }
465 e.Lease = binary.BigEndian.Uint32(b)
466 return nil
467 }
468
469
470
471 type EDNS0_LLQ struct {
472 Code uint16
473 Version uint16
474 Opcode uint16
475 Error uint16
476 Id uint64
477 LeaseLife uint32
478 }
479
480
481 func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ }
482
483 func (e *EDNS0_LLQ) pack() ([]byte, error) {
484 b := make([]byte, 18)
485 binary.BigEndian.PutUint16(b[0:], e.Version)
486 binary.BigEndian.PutUint16(b[2:], e.Opcode)
487 binary.BigEndian.PutUint16(b[4:], e.Error)
488 binary.BigEndian.PutUint64(b[6:], e.Id)
489 binary.BigEndian.PutUint32(b[14:], e.LeaseLife)
490 return b, nil
491 }
492
493 func (e *EDNS0_LLQ) unpack(b []byte) error {
494 if len(b) < 18 {
495 return ErrBuf
496 }
497 e.Version = binary.BigEndian.Uint16(b[0:])
498 e.Opcode = binary.BigEndian.Uint16(b[2:])
499 e.Error = binary.BigEndian.Uint16(b[4:])
500 e.Id = binary.BigEndian.Uint64(b[6:])
501 e.LeaseLife = binary.BigEndian.Uint32(b[14:])
502 return nil
503 }
504
505 func (e *EDNS0_LLQ) String() string {
506 s := strconv.FormatUint(uint64(e.Version), 10) + " " + strconv.FormatUint(uint64(e.Opcode), 10) +
507 " " + strconv.FormatUint(uint64(e.Error), 10) + " " + strconv.FormatUint(e.Id, 10) +
508 " " + strconv.FormatUint(uint64(e.LeaseLife), 10)
509 return s
510 }
511
512 func (e *EDNS0_LLQ) copy() EDNS0 {
513 return &EDNS0_LLQ{e.Code, e.Version, e.Opcode, e.Error, e.Id, e.LeaseLife}
514 }
515
516
517 type EDNS0_DAU struct {
518 Code uint16
519 AlgCode []uint8
520 }
521
522
523 func (e *EDNS0_DAU) Option() uint16 { return EDNS0DAU }
524 func (e *EDNS0_DAU) pack() ([]byte, error) { return cloneSlice(e.AlgCode), nil }
525 func (e *EDNS0_DAU) unpack(b []byte) error { e.AlgCode = cloneSlice(b); return nil }
526
527 func (e *EDNS0_DAU) String() string {
528 s := ""
529 for _, alg := range e.AlgCode {
530 if a, ok := AlgorithmToString[alg]; ok {
531 s += " " + a
532 } else {
533 s += " " + strconv.Itoa(int(alg))
534 }
535 }
536 return s
537 }
538 func (e *EDNS0_DAU) copy() EDNS0 { return &EDNS0_DAU{e.Code, e.AlgCode} }
539
540
541 type EDNS0_DHU struct {
542 Code uint16
543 AlgCode []uint8
544 }
545
546
547 func (e *EDNS0_DHU) Option() uint16 { return EDNS0DHU }
548 func (e *EDNS0_DHU) pack() ([]byte, error) { return cloneSlice(e.AlgCode), nil }
549 func (e *EDNS0_DHU) unpack(b []byte) error { e.AlgCode = cloneSlice(b); return nil }
550
551 func (e *EDNS0_DHU) String() string {
552 s := ""
553 for _, alg := range e.AlgCode {
554 if a, ok := HashToString[alg]; ok {
555 s += " " + a
556 } else {
557 s += " " + strconv.Itoa(int(alg))
558 }
559 }
560 return s
561 }
562 func (e *EDNS0_DHU) copy() EDNS0 { return &EDNS0_DHU{e.Code, e.AlgCode} }
563
564
565 type EDNS0_N3U struct {
566 Code uint16
567 AlgCode []uint8
568 }
569
570
571 func (e *EDNS0_N3U) Option() uint16 { return EDNS0N3U }
572 func (e *EDNS0_N3U) pack() ([]byte, error) { return cloneSlice(e.AlgCode), nil }
573 func (e *EDNS0_N3U) unpack(b []byte) error { e.AlgCode = cloneSlice(b); return nil }
574
575 func (e *EDNS0_N3U) String() string {
576
577 s := ""
578 for _, alg := range e.AlgCode {
579 if a, ok := HashToString[alg]; ok {
580 s += " " + a
581 } else {
582 s += " " + strconv.Itoa(int(alg))
583 }
584 }
585 return s
586 }
587 func (e *EDNS0_N3U) copy() EDNS0 { return &EDNS0_N3U{e.Code, e.AlgCode} }
588
589
590 type EDNS0_EXPIRE struct {
591 Code uint16
592 Expire uint32
593 Empty bool
594 }
595
596
597 func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE }
598 func (e *EDNS0_EXPIRE) copy() EDNS0 { return &EDNS0_EXPIRE{e.Code, e.Expire, e.Empty} }
599
600 func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
601 if e.Empty {
602 return []byte{}, nil
603 }
604 b := make([]byte, 4)
605 binary.BigEndian.PutUint32(b, e.Expire)
606 return b, nil
607 }
608
609 func (e *EDNS0_EXPIRE) unpack(b []byte) error {
610 if len(b) == 0 {
611
612 e.Empty = true
613 return nil
614 }
615 if len(b) < 4 {
616 return ErrBuf
617 }
618 e.Expire = binary.BigEndian.Uint32(b)
619 e.Empty = false
620 return nil
621 }
622
623 func (e *EDNS0_EXPIRE) String() (s string) {
624 if e.Empty {
625 return ""
626 }
627 return strconv.FormatUint(uint64(e.Expire), 10)
628 }
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643 type EDNS0_LOCAL struct {
644 Code uint16
645 Data []byte
646 }
647
648
649 func (e *EDNS0_LOCAL) Option() uint16 { return e.Code }
650
651 func (e *EDNS0_LOCAL) String() string {
652 return strconv.FormatInt(int64(e.Code), 10) + ":0x" + hex.EncodeToString(e.Data)
653 }
654
655 func (e *EDNS0_LOCAL) copy() EDNS0 {
656 return &EDNS0_LOCAL{e.Code, cloneSlice(e.Data)}
657 }
658
659 func (e *EDNS0_LOCAL) pack() ([]byte, error) {
660 return cloneSlice(e.Data), nil
661 }
662
663 func (e *EDNS0_LOCAL) unpack(b []byte) error {
664 e.Data = cloneSlice(b)
665 return nil
666 }
667
668
669
670 type EDNS0_TCP_KEEPALIVE struct {
671 Code uint16
672
673
674
675
676 Timeout uint16
677
678
679
680 Length uint16
681 }
682
683
684 func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 { return EDNS0TCPKEEPALIVE }
685
686 func (e *EDNS0_TCP_KEEPALIVE) pack() ([]byte, error) {
687 if e.Timeout > 0 {
688 b := make([]byte, 2)
689 binary.BigEndian.PutUint16(b, e.Timeout)
690 return b, nil
691 }
692 return nil, nil
693 }
694
695 func (e *EDNS0_TCP_KEEPALIVE) unpack(b []byte) error {
696 switch len(b) {
697 case 0:
698 case 2:
699 e.Timeout = binary.BigEndian.Uint16(b)
700 default:
701 return fmt.Errorf("dns: length mismatch, want 0/2 but got %d", len(b))
702 }
703 return nil
704 }
705
706 func (e *EDNS0_TCP_KEEPALIVE) String() string {
707 s := "use tcp keep-alive"
708 if e.Timeout == 0 {
709 s += ", timeout omitted"
710 } else {
711 s += fmt.Sprintf(", timeout %dms", e.Timeout*100)
712 }
713 return s
714 }
715
716 func (e *EDNS0_TCP_KEEPALIVE) copy() EDNS0 { return &EDNS0_TCP_KEEPALIVE{e.Code, e.Timeout, e.Length} }
717
718
719
720
721 type EDNS0_PADDING struct {
722 Padding []byte
723 }
724
725
726 func (e *EDNS0_PADDING) Option() uint16 { return EDNS0PADDING }
727 func (e *EDNS0_PADDING) pack() ([]byte, error) { return cloneSlice(e.Padding), nil }
728 func (e *EDNS0_PADDING) unpack(b []byte) error { e.Padding = cloneSlice(b); return nil }
729 func (e *EDNS0_PADDING) String() string { return fmt.Sprintf("%0X", e.Padding) }
730 func (e *EDNS0_PADDING) copy() EDNS0 { return &EDNS0_PADDING{cloneSlice(e.Padding)} }
731
732
733 const (
734 ExtendedErrorCodeOther uint16 = iota
735 ExtendedErrorCodeUnsupportedDNSKEYAlgorithm
736 ExtendedErrorCodeUnsupportedDSDigestType
737 ExtendedErrorCodeStaleAnswer
738 ExtendedErrorCodeForgedAnswer
739 ExtendedErrorCodeDNSSECIndeterminate
740 ExtendedErrorCodeDNSBogus
741 ExtendedErrorCodeSignatureExpired
742 ExtendedErrorCodeSignatureNotYetValid
743 ExtendedErrorCodeDNSKEYMissing
744 ExtendedErrorCodeRRSIGsMissing
745 ExtendedErrorCodeNoZoneKeyBitSet
746 ExtendedErrorCodeNSECMissing
747 ExtendedErrorCodeCachedError
748 ExtendedErrorCodeNotReady
749 ExtendedErrorCodeBlocked
750 ExtendedErrorCodeCensored
751 ExtendedErrorCodeFiltered
752 ExtendedErrorCodeProhibited
753 ExtendedErrorCodeStaleNXDOMAINAnswer
754 ExtendedErrorCodeNotAuthoritative
755 ExtendedErrorCodeNotSupported
756 ExtendedErrorCodeNoReachableAuthority
757 ExtendedErrorCodeNetworkError
758 ExtendedErrorCodeInvalidData
759 )
760
761
762
763 var ExtendedErrorCodeToString = map[uint16]string{
764 ExtendedErrorCodeOther: "Other",
765 ExtendedErrorCodeUnsupportedDNSKEYAlgorithm: "Unsupported DNSKEY Algorithm",
766 ExtendedErrorCodeUnsupportedDSDigestType: "Unsupported DS Digest Type",
767 ExtendedErrorCodeStaleAnswer: "Stale Answer",
768 ExtendedErrorCodeForgedAnswer: "Forged Answer",
769 ExtendedErrorCodeDNSSECIndeterminate: "DNSSEC Indeterminate",
770 ExtendedErrorCodeDNSBogus: "DNSSEC Bogus",
771 ExtendedErrorCodeSignatureExpired: "Signature Expired",
772 ExtendedErrorCodeSignatureNotYetValid: "Signature Not Yet Valid",
773 ExtendedErrorCodeDNSKEYMissing: "DNSKEY Missing",
774 ExtendedErrorCodeRRSIGsMissing: "RRSIGs Missing",
775 ExtendedErrorCodeNoZoneKeyBitSet: "No Zone Key Bit Set",
776 ExtendedErrorCodeNSECMissing: "NSEC Missing",
777 ExtendedErrorCodeCachedError: "Cached Error",
778 ExtendedErrorCodeNotReady: "Not Ready",
779 ExtendedErrorCodeBlocked: "Blocked",
780 ExtendedErrorCodeCensored: "Censored",
781 ExtendedErrorCodeFiltered: "Filtered",
782 ExtendedErrorCodeProhibited: "Prohibited",
783 ExtendedErrorCodeStaleNXDOMAINAnswer: "Stale NXDOMAIN Answer",
784 ExtendedErrorCodeNotAuthoritative: "Not Authoritative",
785 ExtendedErrorCodeNotSupported: "Not Supported",
786 ExtendedErrorCodeNoReachableAuthority: "No Reachable Authority",
787 ExtendedErrorCodeNetworkError: "Network Error",
788 ExtendedErrorCodeInvalidData: "Invalid Data",
789 }
790
791
792
793 var StringToExtendedErrorCode = reverseInt16(ExtendedErrorCodeToString)
794
795
796
797 type EDNS0_EDE struct {
798 InfoCode uint16
799 ExtraText string
800 }
801
802
803 func (e *EDNS0_EDE) Option() uint16 { return EDNS0EDE }
804 func (e *EDNS0_EDE) copy() EDNS0 { return &EDNS0_EDE{e.InfoCode, e.ExtraText} }
805
806 func (e *EDNS0_EDE) String() string {
807 info := strconv.FormatUint(uint64(e.InfoCode), 10)
808 if s, ok := ExtendedErrorCodeToString[e.InfoCode]; ok {
809 info += fmt.Sprintf(" (%s)", s)
810 }
811 return fmt.Sprintf("%s: (%s)", info, e.ExtraText)
812 }
813
814 func (e *EDNS0_EDE) pack() ([]byte, error) {
815 b := make([]byte, 2+len(e.ExtraText))
816 binary.BigEndian.PutUint16(b[0:], e.InfoCode)
817 copy(b[2:], e.ExtraText)
818 return b, nil
819 }
820
821 func (e *EDNS0_EDE) unpack(b []byte) error {
822 if len(b) < 2 {
823 return ErrBuf
824 }
825 e.InfoCode = binary.BigEndian.Uint16(b[0:])
826 e.ExtraText = string(b[2:])
827 return nil
828 }
829
830
831 type EDNS0_ESU struct {
832 Code uint16
833 Uri string
834 }
835
836
837 func (e *EDNS0_ESU) Option() uint16 { return EDNS0ESU }
838 func (e *EDNS0_ESU) String() string { return e.Uri }
839 func (e *EDNS0_ESU) copy() EDNS0 { return &EDNS0_ESU{e.Code, e.Uri} }
840 func (e *EDNS0_ESU) pack() ([]byte, error) { return []byte(e.Uri), nil }
841 func (e *EDNS0_ESU) unpack(b []byte) error {
842 e.Uri = string(b)
843 return nil
844 }
845
View as plain text