@@ -257,6 +257,121 @@ var _ = Describe("ConditionalUpstreamResolver", Label("conditionalResolver"), fu
257257 })
258258 })
259259
260+ When ("the mapped upstream has no answer and fallbackUpstream is set" , func () {
261+ BeforeEach (func () {
262+ emptyUpstream := NewMockUDPUpstreamServer ().WithAnswerFn (func (request * dns.Msg ) (response * dns.Msg ) {
263+ response = new (dns.Msg )
264+ response .SetReply (request )
265+
266+ return response
267+ })
268+
269+ sutConfig .FallbackUpstream = true
270+ sutConfig .Mapping .Upstreams ["empty.box" ] = []config.Upstream {emptyUpstream .Start ()}
271+ sutConfig .Rewrite = map [string ]string {"source.test" : "empty.box" }
272+ })
273+
274+ It ("should ask the next resolver with the original name" , func () {
275+ var seen string
276+
277+ m = & mockResolver {}
278+ m .On ("Resolve" , mock .Anything ).Return (& Response {Res : new (dns.Msg )}, nil )
279+ m .ResolveFn = func (_ context.Context , req * Request ) (* Response , error ) {
280+ seen = req .Req .Question [0 ].Name
281+ resp , err := util .NewMsgWithAnswer (seen , 250 , A , "192.192.192.192" )
282+ Expect (err ).Should (Succeed ())
283+
284+ return & Response {Res : resp , RType : ResponseTypeRESOLVED , Reason : "RESOLVED" }, nil
285+ }
286+ sut .Next (m )
287+
288+ Expect (sut .Resolve (ctx , newRequest ("www.source.test." , A ))).
289+ Should (
290+ SatisfyAll (
291+ BeDNSRecord ("www.source.test." , A , "192.192.192.192" ),
292+ HaveResponseType (ResponseTypeRESOLVED ),
293+ HaveReturnCode (dns .RcodeSuccess ),
294+ ))
295+
296+ Expect (seen ).Should (Equal ("www.source.test." ))
297+ })
298+ })
299+
300+ When ("the mapped upstream fails and fallbackUpstream is set" , func () {
301+ BeforeEach (func () {
302+ deadUpstream := NewMockUDPUpstreamServer ().WithAnswerRR ("dead.box. 123 IN A 1.2.3.4" )
303+ upstream := deadUpstream .Start ()
304+ deadUpstream .Close ()
305+
306+ sutConfig .FallbackUpstream = true
307+ sutConfig .Mapping .Upstreams ["dead.box" ] = []config.Upstream {upstream }
308+ sutConfig .Rewrite = map [string ]string {"source.test" : "dead.box" }
309+ })
310+
311+ It ("should ask the next resolver with the original name" , func () {
312+ var seen string
313+
314+ m = & mockResolver {}
315+ m .On ("Resolve" , mock .Anything ).Return (& Response {Res : new (dns.Msg )}, nil )
316+ m .ResolveFn = func (_ context.Context , req * Request ) (* Response , error ) {
317+ seen = req .Req .Question [0 ].Name
318+ resp , err := util .NewMsgWithAnswer (seen , 250 , A , "192.192.192.192" )
319+ Expect (err ).Should (Succeed ())
320+
321+ return & Response {Res : resp , RType : ResponseTypeRESOLVED , Reason : "RESOLVED" }, nil
322+ }
323+ sut .Next (m )
324+
325+ Expect (sut .Resolve (ctx , newRequest ("www.source.test." , A ))).
326+ Should (HaveResponseType (ResponseTypeRESOLVED ))
327+
328+ Expect (seen ).Should (Equal ("www.source.test." ))
329+ })
330+ })
331+
332+ When ("the mapped upstream fails and fallbackUpstream is not set" , func () {
333+ BeforeEach (func () {
334+ deadUpstream := NewMockUDPUpstreamServer ().WithAnswerRR ("dead.box. 123 IN A 1.2.3.4" )
335+ upstream := deadUpstream .Start ()
336+ deadUpstream .Close ()
337+
338+ sutConfig .Mapping .Upstreams ["dead.box" ] = []config.Upstream {upstream }
339+ sutConfig .Rewrite = map [string ]string {"source.test" : "dead.box" }
340+ })
341+
342+ It ("should return the error" , func () {
343+ _ , err := sut .Resolve (ctx , newRequest ("www.source.test." , A ))
344+ Expect (err ).Should (HaveOccurred ())
345+ Expect (m .Calls ).Should (BeEmpty ())
346+ })
347+ })
348+
349+ When ("the mapped upstream has no answer and fallbackUpstream is not set" , func () {
350+ BeforeEach (func () {
351+ emptyUpstream := NewMockUDPUpstreamServer ().WithAnswerFn (func (request * dns.Msg ) (response * dns.Msg ) {
352+ response = new (dns.Msg )
353+ response .SetReply (request )
354+
355+ return response
356+ })
357+
358+ sutConfig .Mapping .Upstreams ["empty.box" ] = []config.Upstream {emptyUpstream .Start ()}
359+ sutConfig .Rewrite = map [string ]string {"source.test" : "empty.box" }
360+ })
361+
362+ It ("should return the empty answer and not ask the next resolver" , func () {
363+ Expect (sut .Resolve (ctx , newRequest ("www.source.test." , A ))).
364+ Should (
365+ SatisfyAll (
366+ HaveNoAnswer (),
367+ HaveResponseType (ResponseTypeCONDITIONAL ),
368+ HaveReturnCode (dns .RcodeSuccess ),
369+ ))
370+
371+ Expect (m .Calls ).Should (BeEmpty ())
372+ })
373+ })
374+
260375 When ("request does not match rewrite rule but matches conditional mapping" , func () {
261376 It ("should not rewrite and resolve via conditional upstream" , func () {
262377 // Direct request to fritz.box (no rewrite)
0 commit comments