github.com/v2fly/v2ray-core/v4@v4.45.2/app/dns/dnscommon_test.go (about)

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