@@ -1329,6 +1329,74 @@ var _ = Describe("Running DNS server", func() {
13291329 })
13301330 })
13311331
1332+ When ("the client sent a DNS Cookie" , func () {
1333+ // Blocky doesn't implement DNS Cookies (RFC 7873): it can neither produce a Server
1334+ // Cookie of its own nor validate one a client returns. An upstream's cookie must
1335+ // therefore not reach the client, and the client's cookie must not reach an upstream.
1336+ const (
1337+ clientCookie = "0102030405060708"
1338+ serverCookie = "1112131415161718"
1339+ )
1340+
1341+ var upstreamRequest * dns.Msg
1342+
1343+ // chainWithUpstreamCookie records the request as the chain saw it and answers like a
1344+ // cookie-supporting upstream.
1345+ chainWithUpstreamCookie := func (req * model.Request ) * dns.Msg {
1346+ upstreamRequest = req .Req .Copy ()
1347+
1348+ res := chainResponse .SetReply (req .Req )
1349+ res .SetEdns0 (4096 , false )
1350+ util .SetEdns0Option (res , & dns.EDNS0_COOKIE {
1351+ Code : dns .EDNS0COOKIE , Cookie : clientCookie + serverCookie ,
1352+ })
1353+
1354+ return res
1355+ }
1356+
1357+ resolveWithCookie := func (udpSize uint16 , do bool ) * model.Response {
1358+ s := newServerWithChain (chainWithUpstreamCookie )
1359+
1360+ clientMsg := util .NewMsgWithQuestion ("example.com." , A )
1361+ clientMsg .SetEdns0 (udpSize , do )
1362+ util .SetEdns0Option (clientMsg , & dns.EDNS0_COOKIE {Code : dns .EDNS0COOKIE , Cookie : clientCookie })
1363+
1364+ _ , req := newRequest (ctx , net .ParseIP ("1.2.3.4" ), "" , model .RequestProtocolUDP , clientMsg )
1365+
1366+ resp , err := s .resolve (ctx , req )
1367+ Expect (err ).Should (Succeed ())
1368+
1369+ return resp
1370+ }
1371+
1372+ BeforeEach (func () {
1373+ upstreamRequest = nil
1374+ })
1375+
1376+ It ("removes the upstream's COOKIE option from the response" , func () {
1377+ resp := resolveWithCookie (1232 , false )
1378+
1379+ Expect (resp .Res ).ShouldNot (HaveEdnsOption (dns .EDNS0COOKIE ))
1380+ Expect (resp .Res .IsEdns0 ()).ShouldNot (BeNil ())
1381+ })
1382+
1383+ It ("does not forward the client's COOKIE option upstream" , func () {
1384+ resolveWithCookie (1232 , false )
1385+
1386+ Expect (upstreamRequest ).ShouldNot (BeNil ())
1387+ Expect (upstreamRequest ).ShouldNot (HaveEdnsOption (dns .EDNS0COOKIE ))
1388+ })
1389+
1390+ It ("keeps the OPT record sent upstream when the cookie was the only option" , func () {
1391+ resolveWithCookie (1232 , true )
1392+
1393+ Expect (upstreamRequest ).ShouldNot (BeNil ())
1394+ Expect (upstreamRequest .IsEdns0 ()).ShouldNot (BeNil ())
1395+ Expect (upstreamRequest .IsEdns0 ().Do ()).Should (BeTrue ())
1396+ Expect (upstreamRequest .IsEdns0 ().UDPSize ()).Should (BeNumerically ("==" , 1232 ))
1397+ })
1398+ })
1399+
13321400 When ("the client left the DO bit clear" , func () {
13331401 // RFC 4035 section 3.2.1: the DNSSEC records the chain requested upstream on the
13341402 // client's behalf must not be added to the response of a client that didn't ask.
0 commit comments