github.com/phuslu/fastdns@v0.8.3-0.20240310041952-69506fc67dd1/handler_test.go (about)

     1  package fastdns
     2  
     3  import (
     4  	"encoding/hex"
     5  	"net"
     6  	"net/netip"
     7  	"testing"
     8  )
     9  
    10  func mockMessage() (msg *Message) {
    11  	// domain = hk.phus.lu
    12  	payload, _ := hex.DecodeString("00028180000100010000000002686b0470687573026c750000010001c00c000100010000012b0004771c56be")
    13  
    14  	msg = AcquireMessage()
    15  	err := ParseMessage(msg, payload, true)
    16  	if err != nil {
    17  		panic(err)
    18  	}
    19  
    20  	return
    21  }
    22  
    23  func TestHandlerError(t *testing.T) {
    24  	var cases = []struct {
    25  		Hex   string
    26  		Rcode Rcode
    27  	}{
    28  		{
    29  			"000281830000000000000000",
    30  			RcodeNXDomain,
    31  		},
    32  	}
    33  
    34  	rw, req := &MemResponseWriter{}, mockMessage()
    35  
    36  	if rw.RemoteAddr().IsValid() {
    37  		t.Errorf("MemResponseWriter shall return empty addr")
    38  	}
    39  	if rw.LocalAddr().IsValid() {
    40  		t.Errorf("MemResponseWriter shall return empty addr")
    41  	}
    42  	for _, c := range cases {
    43  		Error(rw, req, c.Rcode)
    44  		if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want {
    45  			t.Errorf("Error(%v) error got=%#v want=%#v", c.Rcode, got, want)
    46  		}
    47  	}
    48  }
    49  
    50  func TestHandlerHost1(t *testing.T) {
    51  	var cases = []struct {
    52  		Hex string
    53  		IP  netip.Addr
    54  		TTL uint32
    55  	}{
    56  		{
    57  			"00028180000100010000000002686b0470687573026c750000010001c00c000100010000012c000401020408",
    58  			netip.AddrFrom4([4]byte{1, 2, 4, 8}),
    59  			300,
    60  		},
    61  	}
    62  
    63  	rw, req := &MemResponseWriter{}, mockMessage()
    64  	for _, c := range cases {
    65  		HOST1(rw, req, c.TTL, c.IP)
    66  		if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want {
    67  			t.Errorf("HOST1(%v) error got=%#v want=%#v", c.IP, got, want)
    68  		}
    69  	}
    70  }
    71  
    72  func TestHandlerHost(t *testing.T) {
    73  	var cases = []struct {
    74  		Hex string
    75  		IP  netip.Addr
    76  		TTL uint32
    77  	}{
    78  		{
    79  			"00028180000100010000000002686b0470687573026c750000010001c00c000100010000012c000401020408",
    80  			netip.AddrFrom4([4]byte{1, 2, 4, 8}),
    81  			300,
    82  		},
    83  	}
    84  
    85  	rw, req := &MemResponseWriter{}, mockMessage()
    86  	for _, c := range cases {
    87  		HOST(rw, req, c.TTL, []netip.Addr{c.IP})
    88  		if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want {
    89  			t.Errorf("HOST(%v) error got=%#v want=%#v", c.IP, got, want)
    90  		}
    91  	}
    92  }
    93  
    94  func TestHandlerCNAME(t *testing.T) {
    95  	var cases = []struct {
    96  		Hex   string
    97  		CNAME string
    98  		TTL   uint32
    99  	}{
   100  		{
   101  			"00028180000100010000000002686b0470687573026c750000010001c00c000500010000012c001305636e616d65076578616d706c6503636f6d00",
   102  			"cname.example.com",
   103  			300,
   104  		},
   105  	}
   106  
   107  	rw, req := &MemResponseWriter{}, mockMessage()
   108  	for _, c := range cases {
   109  		CNAME(rw, req, c.TTL, []string{c.CNAME}, nil)
   110  		if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want {
   111  			t.Errorf("CNAME(%v) error got=%#v want=%#v", c.CNAME, got, want)
   112  		}
   113  	}
   114  }
   115  
   116  func TestHandlerSRV(t *testing.T) {
   117  	var cases = []struct {
   118  		Hex string
   119  		TTL uint32
   120  		SRV net.SRV
   121  	}{
   122  		{
   123  			"00028180000100010000000002686b0470687573026c750000010001c00c002100010000012c001c03e803e81f41087365727669636531076578616d706c6503636f6d00",
   124  			300,
   125  			net.SRV{Target: "service1.example.com", Port: 8001, Priority: 1000, Weight: 1000},
   126  		},
   127  	}
   128  
   129  	rw, req := &MemResponseWriter{}, mockMessage()
   130  	for _, c := range cases {
   131  		SRV(rw, req, c.TTL, []net.SRV{c.SRV})
   132  		if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want {
   133  			t.Errorf("SRV(%v) error got=%#v want=%#v", c.SRV, got, want)
   134  		}
   135  	}
   136  }
   137  
   138  func TestHandlerNS(t *testing.T) {
   139  	var cases = []struct {
   140  		Hex        string
   141  		TTL        uint32
   142  		Nameserver net.NS
   143  	}{
   144  		{
   145  			"00028180000100010000000002686b0470687573026c750000010001c00c000200010000012c0010026e73076578616d706c6503636f6d00",
   146  			300,
   147  			net.NS{Host: "ns.example.com"},
   148  		},
   149  	}
   150  
   151  	rw, req := &MemResponseWriter{}, mockMessage()
   152  	for _, c := range cases {
   153  		NS(rw, req, c.TTL, []net.NS{c.Nameserver})
   154  		if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want {
   155  			t.Errorf("NS(%v) error got=%#v want=%#v", c.Nameserver, got, want)
   156  		}
   157  	}
   158  }
   159  
   160  func TestHandlerSOA(t *testing.T) {
   161  	var cases = []struct {
   162  		Hex     string
   163  		TTL     uint32
   164  		MName   net.NS
   165  		RName   net.NS
   166  		Serial  uint32
   167  		Refresh uint32
   168  		Retry   uint32
   169  		Expire  uint32
   170  		Minimum uint32
   171  	}{
   172  		{
   173  			"00028180000100010000000002686b0470687573026c750000010001c00c000600010000012c003a036e733106676f6f676c6503636f6d0009646e732d61646d696e06676f6f676c6503636f6d00400000000000038400000384000007080000003c",
   174  			300,
   175  			net.NS{Host: "ns1.google.com"},
   176  			net.NS{Host: "dns-admin.google.com"},
   177  			1073741824,
   178  			900,
   179  			900,
   180  			1800,
   181  			60,
   182  		},
   183  	}
   184  
   185  	rw, req := &MemResponseWriter{}, mockMessage()
   186  	for _, c := range cases {
   187  		SOA(rw, req, c.TTL, c.MName, c.RName, c.Serial, c.Refresh, c.Retry, c.Expire, c.Minimum)
   188  		if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want {
   189  			t.Errorf("SOA(%v) error got=%#v want=%#v", c.MName, got, want)
   190  		}
   191  	}
   192  }
   193  
   194  func TestHandlerMX(t *testing.T) {
   195  	var cases = []struct {
   196  		Hex string
   197  		TTL uint32
   198  		MX  net.MX
   199  	}{
   200  		{
   201  			"00028180000100010000000002686b0470687573026c750000010001c00c000f00010000012c0013000a03707472076578616d706c65036f726700",
   202  			300,
   203  			net.MX{Host: "ptr.example.org", Pref: 10},
   204  		},
   205  	}
   206  
   207  	rw, req := &MemResponseWriter{}, mockMessage()
   208  	for _, c := range cases {
   209  		MX(rw, req, c.TTL, []net.MX{c.MX})
   210  		if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want {
   211  			t.Errorf("MX(%v) error got=%#v want=%#v", c.MX, got, want)
   212  		}
   213  	}
   214  }
   215  
   216  func TestHandlerPTR(t *testing.T) {
   217  	var cases = []struct {
   218  		Hex string
   219  		PTR string
   220  		TTL uint32
   221  	}{
   222  		{
   223  			"00028180000100010000000002686b0470687573026c750000010001c00c000c00010000012c001103707472076578616d706c65036f726700",
   224  			"ptr.example.org",
   225  			300,
   226  		},
   227  	}
   228  
   229  	rw, req := &MemResponseWriter{}, mockMessage()
   230  	for _, c := range cases {
   231  		PTR(rw, req, c.TTL, c.PTR)
   232  		if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want {
   233  			t.Errorf("PTR(%v) error got=%#v want=%#v", c.PTR, got, want)
   234  		}
   235  	}
   236  }
   237  
   238  func TestHandlerTXT(t *testing.T) {
   239  	var cases = []struct {
   240  		Hex string
   241  		TXT string
   242  		TTL uint32
   243  	}{
   244  		{
   245  			"00028180000100010000000002686b0470687573026c750000010001c00c001000010000012c000e0d69616d617478747265636f7264",
   246  			"iamatxtrecord",
   247  			300,
   248  		},
   249  	}
   250  
   251  	rw, req := &MemResponseWriter{}, mockMessage()
   252  	for _, c := range cases {
   253  		TXT(rw, req, c.TTL, c.TXT)
   254  		if got, want := hex.EncodeToString(rw.Data), c.Hex; got != want {
   255  			t.Errorf("TXT(%v) error got=%#v want=%#v", c.TXT, got, want)
   256  		}
   257  	}
   258  }
   259  
   260  type nilResponseWriter struct{}
   261  
   262  func (rw *nilResponseWriter) RemoteAddr() netip.AddrPort { return netip.AddrPort{} }
   263  
   264  func (rw *nilResponseWriter) LocalAddr() netip.AddrPort { return netip.AddrPort{} }
   265  
   266  func (rw *nilResponseWriter) Write(p []byte) (n int, err error) { return len(p), nil }
   267  
   268  func BenchmarkHOST1(b *testing.B) {
   269  	req := mockMessage()
   270  	ip := netip.AddrFrom4([4]byte{8, 8, 8, 8})
   271  	for i := 0; i < b.N; i++ {
   272  		HOST1(&nilResponseWriter{}, req, 3000, ip)
   273  	}
   274  }
   275  
   276  func BenchmarkHOST(b *testing.B) {
   277  	req := mockMessage()
   278  	ips := []netip.Addr{netip.AddrFrom4([4]byte{8, 8, 8, 8})}
   279  	for i := 0; i < b.N; i++ {
   280  		HOST(&nilResponseWriter{}, req, 3000, ips)
   281  	}
   282  }
   283  
   284  func BenchmarkCNAME(b *testing.B) {
   285  	req := mockMessage()
   286  	cnames := []string{"cname.example.org"}
   287  	for i := 0; i < b.N; i++ {
   288  		CNAME(&nilResponseWriter{}, req, 3000, cnames, nil)
   289  	}
   290  }
   291  
   292  func BenchmarkSRV(b *testing.B) {
   293  	req := mockMessage()
   294  	srv := net.SRV{Target: "service1.example.org", Port: 8001, Priority: 1000, Weight: 1000}
   295  	for i := 0; i < b.N; i++ {
   296  		SRV(&nilResponseWriter{}, req, 3000, []net.SRV{srv})
   297  	}
   298  }
   299  
   300  func BenchmarkNS(b *testing.B) {
   301  	req := mockMessage()
   302  	nameservers := []net.NS{{Host: "ns1.google.com"}, {Host: "ns2.google.com"}}
   303  	for i := 0; i < b.N; i++ {
   304  		NS(&nilResponseWriter{}, req, 3000, nameservers)
   305  	}
   306  }
   307  
   308  func BenchmarkSOA(b *testing.B) {
   309  	req := mockMessage()
   310  	for i := 0; i < b.N; i++ {
   311  		SOA(&nilResponseWriter{}, req, 3000, net.NS{Host: "ns1.google.com"}, net.NS{Host: "dns-admin.google.com"}, 42, 900, 900, 1800, 60)
   312  	}
   313  }
   314  
   315  func BenchmarkPTR(b *testing.B) {
   316  	req := mockMessage()
   317  	ptr := "ptr.example.org"
   318  	for i := 0; i < b.N; i++ {
   319  		PTR(&nilResponseWriter{}, req, 3000, ptr)
   320  	}
   321  }
   322  
   323  func BenchmarkMX(b *testing.B) {
   324  	req := mockMessage()
   325  	mx := net.MX{Host: "mail.google.com", Pref: 100}
   326  	for i := 0; i < b.N; i++ {
   327  		MX(&nilResponseWriter{}, req, 3000, []net.MX{mx})
   328  	}
   329  }
   330  
   331  func BenchmarkTXT(b *testing.B) {
   332  	req := mockMessage()
   333  	txt := "iamatxtrecord"
   334  	for i := 0; i < b.N; i++ {
   335  		TXT(&nilResponseWriter{}, req, 3000, txt)
   336  	}
   337  }