@@ -13,6 +13,7 @@ import (
13
13
"net"
14
14
"net/netip"
15
15
"runtime"
16
+ "strings"
16
17
"testing"
17
18
"time"
18
19
@@ -67,6 +68,72 @@ func createListener6(t *testing.T) *net.UDPConn {
67
68
return sock
68
69
}
69
70
71
+ func sendAnswer (t * testing.T , sock * net.UDPConn , dst net.Addr , queryID uint16 , name string , ip string ) {
72
+ t .Helper ()
73
+
74
+ answer , err := createAnswer (queryID , name , netip .MustParseAddr (ip ))
75
+ check (t , err )
76
+
77
+ answerBytes , err := answer .Pack ()
78
+ check (t , err )
79
+
80
+ _ , err = sock .WriteTo (answerBytes , dst )
81
+ check (t , err )
82
+ }
83
+
84
+ // createSimpleDNSResponder creates a case-insensitive DNS responder that always
85
+ // responds with responseName. This function is required because the actual
86
+ // responder will respond with the exact queried name, while we want to test
87
+ // responding with a different variation of uppercase/lowercase letters.
88
+ //
89
+ // The caller of this function must call sock.Close().
90
+ func createSimpleDNSResponder (t * testing.T , recordType dnsmessage.Type , name string , ip string ) * net.UDPConn {
91
+ t .Helper ()
92
+ sock := createListener4 (t )
93
+
94
+ if ! strings .HasSuffix (name , "." ) {
95
+ name += "."
96
+ }
97
+
98
+ go func () {
99
+ defer sock .Close () //nolint:errcheck
100
+
101
+ buf := make ([]byte , 65536 )
102
+
103
+ for {
104
+ n , addr , err := sock .ReadFromUDP (buf )
105
+ if errors .Is (err , net .ErrClosed ) {
106
+ return
107
+ }
108
+ check (t , err )
109
+
110
+ parser := dnsmessage.Parser {}
111
+ header , err := parser .Start (buf [:n ])
112
+ check (t , err )
113
+
114
+ for {
115
+ question , err := parser .Question ()
116
+ if errors .Is (err , dnsmessage .ErrSectionDone ) {
117
+ break
118
+ }
119
+ check (t , err )
120
+
121
+ if question .Type != recordType {
122
+ continue
123
+ }
124
+
125
+ if ! strings .EqualFold (question .Name .String (), name ) {
126
+ continue
127
+ }
128
+
129
+ sendAnswer (t , sock , addr , header .ID , name , ip )
130
+ }
131
+ }
132
+ }()
133
+
134
+ return sock
135
+ }
136
+
70
137
func TestValidCommunication (t * testing.T ) {
71
138
lim := test .TimeOut (time .Second * 10 )
72
139
defer lim .Stop ()
@@ -597,6 +664,65 @@ func TestValidCommunicationIPv64Mixed(t *testing.T) {
597
664
}
598
665
}
599
666
667
+ func TestLocalNameCaseInsensitivity (t * testing.T ) {
668
+ lim := test .TimeOut (time .Second * 10 )
669
+ defer lim .Stop ()
670
+
671
+ report := test .CheckRoutines (t )
672
+ defer report ()
673
+
674
+ loopbackIP := net .ParseIP ("127.0.0.1" )
675
+
676
+ aSock := createListener4 (t )
677
+ aServer , err := Server (ipv4 .NewPacketConn (aSock ), nil , & Config {
678
+ LocalNames : []string {"pion-mdns-1.local" },
679
+ LocalAddress : loopbackIP ,
680
+ IncludeLoopback : true ,
681
+ })
682
+ check (t , err )
683
+
684
+ tests := []string {"pion-mdns-1.local" , "PION-MDNS-1.local" , "pion-MDNS-1.local" }
685
+ for _ , test := range tests {
686
+ t .Run (test , func (t * testing.T ) {
687
+ _ , addr , err := aServer .QueryAddr (context .Background (), test )
688
+ check (t , err )
689
+ if addr .String () != loopbackIP .String () {
690
+ t .Fatalf ("address mismatch: expected %s, but got %v\n " , localAddress , addr )
691
+ }
692
+ })
693
+ }
694
+
695
+ check (t , aServer .Close ())
696
+ }
697
+
698
+ func TestCommunicationCaseInsensitivity (t * testing.T ) {
699
+ lim := test .TimeOut (time .Second * 10 )
700
+ defer lim .Stop ()
701
+
702
+ report := test .CheckRoutines (t )
703
+ defer report ()
704
+
705
+ aSock := createSimpleDNSResponder (t , dnsmessage .TypeA , "pion-MDNS-1.local" , localAddress )
706
+
707
+ bSock := createListener4 (t )
708
+ bServer , err := Server (ipv4 .NewPacketConn (bSock ), nil , & Config {})
709
+ check (t , err )
710
+
711
+ tests := []string {"pion-mdns-1.local" , "pion-MDNS-1.local" }
712
+ for _ , test := range tests {
713
+ t .Run (test , func (t * testing.T ) {
714
+ _ , addr , err := bServer .QueryAddr (context .Background (), test )
715
+ check (t , err )
716
+ if addr .String () != localAddress {
717
+ t .Fatalf ("unexpected local address: %v" , addr )
718
+ }
719
+ })
720
+ }
721
+
722
+ check (t , aSock .Close ())
723
+ check (t , bServer .Close ())
724
+ }
725
+
600
726
func TestMultipleClose (t * testing.T ) {
601
727
lim := test .TimeOut (time .Second * 10 )
602
728
defer lim .Stop ()
0 commit comments