280 lines
6.2 KiB
Go
280 lines
6.2 KiB
Go
package dns
|
|
|
|
import (
|
|
"bytes"
|
|
"net"
|
|
"testing"
|
|
)
|
|
|
|
func TestOPTTtl(t *testing.T) {
|
|
e := &OPT{}
|
|
e.Hdr.Name = "."
|
|
e.Hdr.Rrtype = TypeOPT
|
|
|
|
// verify the default setting of DO=0
|
|
if e.Do() {
|
|
t.Errorf("DO bit should be zero")
|
|
}
|
|
|
|
// There are 6 possible invocations of SetDo():
|
|
//
|
|
// 1. Starting with DO=0, using SetDo()
|
|
// 2. Starting with DO=0, using SetDo(true)
|
|
// 3. Starting with DO=0, using SetDo(false)
|
|
// 4. Starting with DO=1, using SetDo()
|
|
// 5. Starting with DO=1, using SetDo(true)
|
|
// 6. Starting with DO=1, using SetDo(false)
|
|
|
|
// verify that invoking SetDo() sets DO=1 (TEST #1)
|
|
e.SetDo()
|
|
if !e.Do() {
|
|
t.Errorf("DO bit should be non-zero")
|
|
}
|
|
// verify that using SetDo(true) works when DO=1 (TEST #5)
|
|
e.SetDo(true)
|
|
if !e.Do() {
|
|
t.Errorf("DO bit should still be non-zero")
|
|
}
|
|
// verify that we can use SetDo(false) to set DO=0 (TEST #6)
|
|
e.SetDo(false)
|
|
if e.Do() {
|
|
t.Errorf("DO bit should be zero")
|
|
}
|
|
// verify that if we call SetDo(false) when DO=0 that it is unchanged (TEST #3)
|
|
e.SetDo(false)
|
|
if e.Do() {
|
|
t.Errorf("DO bit should still be zero")
|
|
}
|
|
// verify that using SetDo(true) works for DO=0 (TEST #2)
|
|
e.SetDo(true)
|
|
if !e.Do() {
|
|
t.Errorf("DO bit should be non-zero")
|
|
}
|
|
// verify that using SetDo() works for DO=1 (TEST #4)
|
|
e.SetDo()
|
|
if !e.Do() {
|
|
t.Errorf("DO bit should be non-zero")
|
|
}
|
|
|
|
if e.Version() != 0 {
|
|
t.Errorf("version should be non-zero")
|
|
}
|
|
|
|
e.SetVersion(42)
|
|
if e.Version() != 42 {
|
|
t.Errorf("set 42, expected %d, got %d", 42, e.Version())
|
|
}
|
|
|
|
e.SetExtendedRcode(42)
|
|
// ExtendedRcode has the last 4 bits set to 0.
|
|
if e.ExtendedRcode() != 42&0xFFFFFFF0 {
|
|
t.Errorf("set 42, expected %d, got %d", 42&0xFFFFFFF0, e.ExtendedRcode())
|
|
}
|
|
|
|
// This will reset the 8 upper bits of the extended rcode
|
|
e.SetExtendedRcode(RcodeNotAuth)
|
|
if e.ExtendedRcode() != 0 {
|
|
t.Errorf("Setting a non-extended rcode is expected to set extended rcode to 0, got: %d", e.ExtendedRcode())
|
|
}
|
|
}
|
|
|
|
func TestEDNS0_SUBNETUnpack(t *testing.T) {
|
|
for _, ip := range []net.IP{
|
|
net.IPv4(0xde, 0xad, 0xbe, 0xef),
|
|
net.ParseIP("192.0.2.1"),
|
|
net.ParseIP("2001:db8::68"),
|
|
} {
|
|
var s1 EDNS0_SUBNET
|
|
s1.Address = ip
|
|
|
|
if ip.To4() == nil {
|
|
s1.Family = 2
|
|
s1.SourceNetmask = net.IPv6len * 8
|
|
} else {
|
|
s1.Family = 1
|
|
s1.SourceNetmask = net.IPv4len * 8
|
|
}
|
|
|
|
b, err := s1.pack()
|
|
if err != nil {
|
|
t.Fatalf("failed to pack: %v", err)
|
|
}
|
|
|
|
var s2 EDNS0_SUBNET
|
|
if err := s2.unpack(b); err != nil {
|
|
t.Fatalf("failed to unpack: %v", err)
|
|
}
|
|
|
|
if !ip.Equal(s2.Address) {
|
|
t.Errorf("address different after unpacking; expected %s, got %s", ip, s2.Address)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestEDNS0_UL(t *testing.T) {
|
|
cases := []struct {
|
|
l uint32
|
|
kl uint32
|
|
}{
|
|
{0x01234567, 0},
|
|
{0x76543210, 0xFEDCBA98},
|
|
}
|
|
for _, c := range cases {
|
|
expect := EDNS0_UL{EDNS0UL, c.l, c.kl}
|
|
b, err := expect.pack()
|
|
if err != nil {
|
|
t.Fatalf("failed to pack: %v", err)
|
|
}
|
|
actual := EDNS0_UL{EDNS0UL, ^uint32(0), ^uint32(0)}
|
|
if err := actual.unpack(b); err != nil {
|
|
t.Fatalf("failed to unpack: %v", err)
|
|
}
|
|
if expect != actual {
|
|
t.Errorf("unpacked option is different; expected %v, got %v", expect, actual)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestZ(t *testing.T) {
|
|
e := &OPT{}
|
|
e.Hdr.Name = "."
|
|
e.Hdr.Rrtype = TypeOPT
|
|
e.SetVersion(8)
|
|
e.SetDo()
|
|
if e.Z() != 0 {
|
|
t.Errorf("expected Z of 0, got %d", e.Z())
|
|
}
|
|
e.SetZ(5)
|
|
if e.Z() != 5 {
|
|
t.Errorf("expected Z of 5, got %d", e.Z())
|
|
}
|
|
e.SetZ(0xFFFF)
|
|
if e.Z() != 0x7FFF {
|
|
t.Errorf("expected Z of 0x7FFFF, got %d", e.Z())
|
|
}
|
|
if e.Version() != 8 {
|
|
t.Errorf("expected version to still be 8, got %d", e.Version())
|
|
}
|
|
if !e.Do() {
|
|
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)
|
|
}
|
|
}
|
|
|
|
func TestEDNS0_TCP_KEEPALIVE_unpack(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
b []byte
|
|
expected uint16
|
|
expectedErr bool
|
|
}{
|
|
{
|
|
name: "empty",
|
|
b: []byte{},
|
|
expected: 0,
|
|
},
|
|
{
|
|
name: "timeout 1",
|
|
b: []byte{0, 1},
|
|
expected: 1,
|
|
},
|
|
{
|
|
name: "invalid",
|
|
b: []byte{0, 1, 3},
|
|
expectedErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
e := &EDNS0_TCP_KEEPALIVE{}
|
|
err := e.unpack(tc.b)
|
|
if err != nil && !tc.expectedErr {
|
|
t.Error("failed to unpack, expected no error")
|
|
}
|
|
if err == nil && tc.expectedErr {
|
|
t.Error("unpacked, but expected an error")
|
|
}
|
|
if e.Timeout != tc.expected {
|
|
t.Errorf("invalid timeout, actual: %d, expected: %d", e.Timeout, tc.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEDNS0_TCP_KEEPALIVE_pack(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
edns *EDNS0_TCP_KEEPALIVE
|
|
expected []byte
|
|
}{
|
|
{
|
|
name: "empty",
|
|
edns: &EDNS0_TCP_KEEPALIVE{
|
|
Code: EDNS0TCPKEEPALIVE,
|
|
Timeout: 0,
|
|
},
|
|
expected: nil,
|
|
},
|
|
{
|
|
name: "timeout 1",
|
|
edns: &EDNS0_TCP_KEEPALIVE{
|
|
Code: EDNS0TCPKEEPALIVE,
|
|
Timeout: 1,
|
|
},
|
|
expected: []byte{0, 1},
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
b, err := tc.edns.pack()
|
|
if err != nil {
|
|
t.Error("expected no error")
|
|
}
|
|
|
|
if tc.expected == nil && b != nil {
|
|
t.Errorf("invalid result, expected nil")
|
|
}
|
|
|
|
res := bytes.Compare(b, tc.expected)
|
|
if res != 0 {
|
|
t.Errorf("invalid result, expected: %v, actual: %v", tc.expected, b)
|
|
}
|
|
})
|
|
}
|
|
}
|