diff --git a/edns.go b/edns.go index c9181783..d070e41b 100644 --- a/edns.go +++ b/edns.go @@ -14,6 +14,7 @@ const ( EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt EDNS0NSID = 0x3 // nsid (See RFC 5001) + EDNS0ESU = 0x4 // ENUM Source-URI draft: https://datatracker.ietf.org/doc/html/draft-kaplan-enum-source-uri-00 EDNS0DAU = 0x5 // DNSSEC Algorithm Understood EDNS0DHU = 0x6 // DS Hash Understood EDNS0N3U = 0x7 // NSEC3 Hash Understood @@ -56,6 +57,8 @@ func makeDataOpt(code uint16) EDNS0 { return new(EDNS0_PADDING) case EDNS0EDE: return new(EDNS0_EDE) + case EDNS0ESU: + return &EDNS0_ESU{Code: EDNS0ESU} default: e := new(EDNS0_LOCAL) e.Code = code @@ -111,6 +114,8 @@ func (rr *OPT) String() string { s += "\n; PADDING: " + o.String() case *EDNS0_EDE: s += "\n; EDE: " + o.String() + case *EDNS0_ESU: + s += "\n; ESU: " + o.String() } } return s @@ -819,3 +824,19 @@ func (e *EDNS0_EDE) unpack(b []byte) error { e.ExtraText = string(b[2:]) return nil } + +// The EDNS0_ESU option for ENUM Source-URI Extension +type EDNS0_ESU struct { + Code uint16 + Uri string +} + +// Option implements the EDNS0 interface. +func (e *EDNS0_ESU) Option() uint16 { return EDNS0ESU } +func (e *EDNS0_ESU) String() string { return e.Uri } +func (e *EDNS0_ESU) copy() EDNS0 { return &EDNS0_ESU{e.Code, e.Uri} } +func (e *EDNS0_ESU) pack() ([]byte, error) { return []byte(e.Uri), nil } +func (e *EDNS0_ESU) unpack(b []byte) error { + e.Uri = string(b) + return nil +} diff --git a/edns_test.go b/edns_test.go index ab2a3b1f..dc4ea7b3 100644 --- a/edns_test.go +++ b/edns_test.go @@ -158,3 +158,37 @@ func TestZ(t *testing.T) { t.Error("expected DO to be set") } } + +func TestEDNS0_ESU(t *testing.T) { + p := []byte{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x29, 0x04, + 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x04, 0x00, 0x24, 0x73, 0x69, 0x70, 0x3A, 0x2B, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x40, 0x74, 0x65, 0x73, 0x74, 0x2E, 0x63, + 0x6F, 0x6D, 0x3B, 0x75, 0x73, 0x65, 0x72, 0x3D, + 0x63, 0x67, 0x72, 0x61, 0x74, 0x65, 0x73, + } + + m := new(Msg) + if err := m.Unpack(p); err != nil { + t.Fatalf("failed to unpack: %v", err) + } + opt := m.IsEdns0() + if opt == nil { + t.Fatalf("expected edns0 option") + } + if len(opt.Option) != 1 { + t.Fatalf("expected only one option: %v", opt.Option) + } + edns0 := opt.Option[0] + esu, ok := edns0.(*EDNS0_ESU) + if !ok { + t.Fatalf("expected option of type EDNS0_ESU, got %t", edns0) + } + expect := "sip:+123456789@test.com;user=cgrates" + if esu.Uri != expect { + t.Errorf("unpacked option is different; expected %v, got %v", expect, esu.Uri) + } +}