@@ -56,6 +56,85 @@ func TestServer_ReadTimeout(t *testing.T) {
5656 testThisServerRespondMessages (t , "tcp" , srv )
5757}
5858
59+ func TestServer_UDPTruncateMessage (t * testing.T ) {
60+ // Create a test server that returns large response which should be
61+ // truncated if sent over UDP
62+ srv := newTestServer (t , & testLargeMsgHandler {})
63+ t .Cleanup (func () {
64+ require .NoError (t , srv .Close ())
65+ })
66+
67+ // Create client and connect
68+ client := & Client {
69+ Timeout : 1 * time .Second ,
70+ Net : "udp" ,
71+ }
72+ serverAddr := fmt .Sprintf ("127.0.0.1:%d" , srv .UDPAddr ().Port )
73+ stamp := dnsstamps.ServerStamp {
74+ ServerAddrStr : serverAddr ,
75+ ServerPk : srv .resolverPk ,
76+ ProviderName : srv .server .ProviderName ,
77+ Proto : dnsstamps .StampProtoTypeDNSCrypt ,
78+ }
79+ ri , err := client .DialStamp (stamp )
80+ require .NoError (t , err )
81+ require .NotNil (t , ri )
82+
83+ // Send a test message and check that the response was truncated
84+ m := createTestMessage ()
85+ res , err := client .Exchange (m , ri )
86+ require .NoError (t , err )
87+ require .NotNil (t , res )
88+ require .Equal (t , dns .RcodeSuccess , res .Rcode )
89+ require .Len (t , res .Answer , 0 )
90+ require .True (t , res .Truncated )
91+ }
92+
93+ func TestServer_UDPEDNS0_NoTruncate (t * testing.T ) {
94+ // Create a test server that returns large response which should be
95+ // truncated if sent over UDP
96+ // However, when EDNS0 is set with the buffer large enough, there should
97+ // be no truncation
98+ srv := newTestServer (t , & testLargeMsgHandler {})
99+ t .Cleanup (func () {
100+ require .NoError (t , srv .Close ())
101+ })
102+
103+ // Create client and connect
104+ client := & Client {
105+ Timeout : 1 * time .Second ,
106+ Net : "udp" ,
107+ UDPSize : 7000 , // make sure the client will be able to read the response
108+ }
109+ serverAddr := fmt .Sprintf ("127.0.0.1:%d" , srv .UDPAddr ().Port )
110+ stamp := dnsstamps.ServerStamp {
111+ ServerAddrStr : serverAddr ,
112+ ServerPk : srv .resolverPk ,
113+ ProviderName : srv .server .ProviderName ,
114+ Proto : dnsstamps .StampProtoTypeDNSCrypt ,
115+ }
116+ ri , err := client .DialStamp (stamp )
117+ require .NoError (t , err )
118+ require .NotNil (t , ri )
119+
120+ // Send a test message with UDP buffer size large enough
121+ // and check that the response was NOT truncated
122+ m := createTestMessage ()
123+ m .Extra = append (m .Extra , & dns.OPT {
124+ Hdr : dns.RR_Header {
125+ Name : "." ,
126+ Rrtype : dns .TypeOPT ,
127+ Class : 2000 , // Set large enough UDPSize here
128+ },
129+ })
130+ res , err := client .Exchange (m , ri )
131+ require .NoError (t , err )
132+ require .NotNil (t , res )
133+ require .Equal (t , dns .RcodeSuccess , res .Rcode )
134+ require .Len (t , res .Answer , 64 )
135+ require .False (t , res .Truncated )
136+ }
137+
59138func testServerServeCert (t * testing.T , network string ) {
60139 srv := newTestServer (t , & testHandler {})
61140 t .Cleanup (func () {
@@ -193,17 +272,44 @@ type testHandler struct{}
193272
194273// ServeDNS - implements Handler interface
195274func (h * testHandler ) ServeDNS (rw ResponseWriter , r * dns.Msg ) error {
196- // Google DNS
197275 res := new (dns.Msg )
198276 res .SetReply (r )
277+
199278 answer := new (dns.A )
200279 answer .Hdr = dns.RR_Header {
201280 Name : r .Question [0 ].Name ,
202281 Rrtype : dns .TypeA ,
203282 Ttl : 300 ,
204283 Class : dns .ClassINET ,
205284 }
285+ // First record is from Google DNS
206286 answer .A = net .IPv4 (8 , 8 , 8 , 8 )
207287 res .Answer = append (res .Answer , answer )
288+
289+ return rw .WriteMsg (res )
290+ }
291+
292+ // testLargeMsgHandler is a handler that returns a huge response
293+ // used for testing messages truncation
294+ type testLargeMsgHandler struct {}
295+
296+ // ServeDNS - implements Handler interface
297+ func (h * testLargeMsgHandler ) ServeDNS (rw ResponseWriter , r * dns.Msg ) error {
298+ res := new (dns.Msg )
299+ res .SetReply (r )
300+
301+ for i := 0 ; i < 64 ; i ++ {
302+ answer := new (dns.A )
303+ answer .Hdr = dns.RR_Header {
304+ Name : r .Question [0 ].Name ,
305+ Rrtype : dns .TypeA ,
306+ Ttl : 300 ,
307+ Class : dns .ClassINET ,
308+ }
309+ answer .A = net .IPv4 (127 , 0 , 0 , byte (i ))
310+ res .Answer = append (res .Answer , answer )
311+ }
312+
313+ res .Compress = true
208314 return rw .WriteMsg (res )
209315}
0 commit comments