github.com/EagleQL/Xray-core@v1.4.3/app/dns/dnscommon_test.go (about)

     1  package dns
     2  
     3  import (
     4  	"math/rand"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/google/go-cmp/cmp"
     9  	"github.com/miekg/dns"
    10  	"github.com/xtls/xray-core/common"
    11  	"github.com/xtls/xray-core/common/net"
    12  	dns_feature "github.com/xtls/xray-core/features/dns"
    13  	"golang.org/x/net/dns/dnsmessage"
    14  )
    15  
    16  func Test_parseResponse(t *testing.T) {
    17  	var p [][]byte
    18  
    19  	ans := new(dns.Msg)
    20  	ans.Id = 0
    21  	p = append(p, common.Must2(ans.Pack()).([]byte))
    22  
    23  	p = append(p, []byte{})
    24  
    25  	ans = new(dns.Msg)
    26  	ans.Id = 1
    27  	ans.Answer = append(ans.Answer,
    28  		common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")).(dns.RR),
    29  		common.Must2(dns.NewRR("google.com. IN CNAME fake.google.com")).(dns.RR),
    30  		common.Must2(dns.NewRR("google.com. IN A 8.8.8.8")).(dns.RR),
    31  		common.Must2(dns.NewRR("google.com. IN A 8.8.4.4")).(dns.RR),
    32  	)
    33  	p = append(p, common.Must2(ans.Pack()).([]byte))
    34  
    35  	ans = new(dns.Msg)
    36  	ans.Id = 2
    37  	ans.Answer = append(ans.Answer,
    38  		common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")).(dns.RR),
    39  		common.Must2(dns.NewRR("google.com. IN CNAME fake.google.com")).(dns.RR),
    40  		common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")).(dns.RR),
    41  		common.Must2(dns.NewRR("google.com. IN CNAME test.google.com")).(dns.RR),
    42  		common.Must2(dns.NewRR("google.com. IN AAAA 2001::123:8888")).(dns.RR),
    43  		common.Must2(dns.NewRR("google.com. IN AAAA 2001::123:8844")).(dns.RR),
    44  	)
    45  	p = append(p, common.Must2(ans.Pack()).([]byte))
    46  
    47  	tests := []struct {
    48  		name    string
    49  		want    *IPRecord
    50  		wantErr bool
    51  	}{
    52  		{"empty",
    53  			&IPRecord{0, []net.Address(nil), time.Time{}, dnsmessage.RCodeSuccess},
    54  			false,
    55  		},
    56  		{"error",
    57  			nil,
    58  			true,
    59  		},
    60  		{"a record",
    61  			&IPRecord{1, []net.Address{net.ParseAddress("8.8.8.8"), net.ParseAddress("8.8.4.4")},
    62  				time.Time{}, dnsmessage.RCodeSuccess},
    63  			false,
    64  		},
    65  		{"aaaa record",
    66  			&IPRecord{2, []net.Address{net.ParseAddress("2001::123:8888"), net.ParseAddress("2001::123:8844")}, time.Time{}, dnsmessage.RCodeSuccess},
    67  			false,
    68  		},
    69  	}
    70  	for i, tt := range tests {
    71  		t.Run(tt.name, func(t *testing.T) {
    72  			got, err := parseResponse(p[i])
    73  			if (err != nil) != tt.wantErr {
    74  				t.Errorf("handleResponse() error = %v, wantErr %v", err, tt.wantErr)
    75  				return
    76  			}
    77  
    78  			if got != nil {
    79  				// reset the time
    80  				got.Expire = time.Time{}
    81  			}
    82  			if cmp.Diff(got, tt.want) != "" {
    83  				t.Errorf(cmp.Diff(got, tt.want))
    84  				// t.Errorf("handleResponse() = %#v, want %#v", got, tt.want)
    85  			}
    86  		})
    87  	}
    88  }
    89  
    90  func Test_buildReqMsgs(t *testing.T) {
    91  	stubID := func() uint16 {
    92  		return uint16(rand.Uint32())
    93  	}
    94  	type args struct {
    95  		domain  string
    96  		option  dns_feature.IPOption
    97  		reqOpts *dnsmessage.Resource
    98  	}
    99  	tests := []struct {
   100  		name string
   101  		args args
   102  		want int
   103  	}{
   104  		{"dual stack", args{"test.com", dns_feature.IPOption{
   105  			IPv4Enable: true,
   106  			IPv6Enable: true,
   107  			FakeEnable: false,
   108  		}, nil}, 2},
   109  		{"ipv4 only", args{"test.com", dns_feature.IPOption{
   110  			IPv4Enable: true,
   111  			IPv6Enable: false,
   112  			FakeEnable: false,
   113  		}, nil}, 1},
   114  		{"ipv6 only", args{"test.com", dns_feature.IPOption{
   115  			IPv4Enable: false,
   116  			IPv6Enable: true,
   117  			FakeEnable: false,
   118  		}, nil}, 1},
   119  		{"none/error", args{"test.com", dns_feature.IPOption{
   120  			IPv4Enable: false,
   121  			IPv6Enable: false,
   122  			FakeEnable: false,
   123  		}, nil}, 0},
   124  	}
   125  	for _, tt := range tests {
   126  		t.Run(tt.name, func(t *testing.T) {
   127  			if got := buildReqMsgs(tt.args.domain, tt.args.option, stubID, tt.args.reqOpts); !(len(got) == tt.want) {
   128  				t.Errorf("buildReqMsgs() = %v, want %v", got, tt.want)
   129  			}
   130  		})
   131  	}
   132  }
   133  
   134  func Test_genEDNS0Options(t *testing.T) {
   135  	type args struct {
   136  		clientIP net.IP
   137  	}
   138  	tests := []struct {
   139  		name string
   140  		args args
   141  		want *dnsmessage.Resource
   142  	}{
   143  		// TODO: Add test cases.
   144  		{"ipv4", args{net.ParseIP("4.3.2.1")}, nil},
   145  		{"ipv6", args{net.ParseIP("2001::4321")}, nil},
   146  	}
   147  	for _, tt := range tests {
   148  		t.Run(tt.name, func(t *testing.T) {
   149  			if got := genEDNS0Options(tt.args.clientIP); got == nil {
   150  				t.Errorf("genEDNS0Options() = %v, want %v", got, tt.want)
   151  			}
   152  		})
   153  	}
   154  }
   155  
   156  func TestFqdn(t *testing.T) {
   157  	type args struct {
   158  		domain string
   159  	}
   160  	tests := []struct {
   161  		name string
   162  		args args
   163  		want string
   164  	}{
   165  		{"with fqdn", args{"www.example.com."}, "www.example.com."},
   166  		{"without fqdn", args{"www.example.com"}, "www.example.com."},
   167  	}
   168  	for _, tt := range tests {
   169  		t.Run(tt.name, func(t *testing.T) {
   170  			if got := Fqdn(tt.args.domain); got != tt.want {
   171  				t.Errorf("Fqdn() = %v, want %v", got, tt.want)
   172  			}
   173  		})
   174  	}
   175  }