mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 10:13:14 -04:00 
			
		
		
		
	plugin/cache: Fix filtering (#4148)
The filtering of DNSSEC records in the cache plugin was not done correctly. Also the change to introduced this bug didn't take into account that the cache - by virtue of differentiating between DNSSEC and no-DNSSEC - relied on not copying the data from the cache. This change copies and then filters the data and factors the filtering into a function that is used in two places (albeit with on ugly boolean parameters to prevent copying things twice). Add tests, do_test.go is moved to test/cache_test.go because the OPT handing is done outside of the cache plugin. The core server re-attaches the correct OPT when replying, so that makes for a better e2e test. Added small unit test for filterRRslice and an explicit test that asks for DNSSEC first and then plain, and vice versa to test cache behavior. Fixes: #4146 Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
		
							
								
								
									
										54
									
								
								plugin/cache/item.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								plugin/cache/item.go
									
									
									
									
										vendored
									
									
								
							| @@ -75,37 +75,10 @@ func (i *item) toMsg(m *dns.Msg, now time.Time, do bool) *dns.Msg { | ||||
| 	m1.Extra = make([]dns.RR, len(i.Extra)) | ||||
|  | ||||
| 	ttl := uint32(i.ttl(now)) | ||||
| 	j := 0 | ||||
| 	for _, r := range i.Answer { | ||||
| 		if !do && isDNSSEC(r) { | ||||
| 			continue | ||||
| 		} | ||||
| 		m1.Answer[j] = dns.Copy(r) | ||||
| 		m1.Answer[j].Header().Ttl = ttl | ||||
| 		j++ | ||||
| 	} | ||||
| 	m1.Answer = m1.Answer[:j] | ||||
| 	j = 0 | ||||
| 	for _, r := range i.Ns { | ||||
| 		if !do && isDNSSEC(r) { | ||||
| 			continue | ||||
| 		} | ||||
| 		m1.Ns[j] = dns.Copy(r) | ||||
| 		m1.Ns[j].Header().Ttl = ttl | ||||
| 		j++ | ||||
| 	} | ||||
| 	m1.Ns = m1.Ns[:j] | ||||
| 	// newItem skips OPT records, so we can just use i.Extra as is. | ||||
| 	j = 0 | ||||
| 	for _, r := range i.Extra { | ||||
| 		if !do && isDNSSEC(r) { | ||||
| 			continue | ||||
| 		} | ||||
| 		m1.Extra[j] = dns.Copy(r) | ||||
| 		m1.Extra[j].Header().Ttl = ttl | ||||
| 		j++ | ||||
| 	} | ||||
| 	m1.Extra = m1.Extra[:j] | ||||
| 	m1.Answer = filterRRSlice(i.Answer, ttl, do, true) | ||||
| 	m1.Ns = filterRRSlice(i.Ns, ttl, do, true) | ||||
| 	m1.Extra = filterRRSlice(i.Extra, ttl, do, true) | ||||
|  | ||||
| 	return m1 | ||||
| } | ||||
|  | ||||
| @@ -113,22 +86,3 @@ func (i *item) ttl(now time.Time) int { | ||||
| 	ttl := int(i.origTTL) - int(now.UTC().Sub(i.stored).Seconds()) | ||||
| 	return ttl | ||||
| } | ||||
|  | ||||
| // isDNSSEC returns true if r is a DNSSEC record. NSEC,NSEC3,DS and RRSIG/SIG | ||||
| // are DNSSEC records. DNSKEYs is not in this list on the assumption that the | ||||
| // client explictly asked for it. | ||||
| func isDNSSEC(r dns.RR) bool { | ||||
| 	switch r.Header().Rrtype { | ||||
| 	case dns.TypeNSEC: | ||||
| 		return true | ||||
| 	case dns.TypeNSEC3: | ||||
| 		return true | ||||
| 	case dns.TypeDS: | ||||
| 		return true | ||||
| 	case dns.TypeRRSIG: | ||||
| 		return true | ||||
| 	case dns.TypeSIG: | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user