mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-30 17:53:21 -04:00 
			
		
		
		
	Ensure cache.ResponseWriter can be used asynchronously during prefetch (#1884)
The default dns.Response implementation of a dns.ResponseWriter will panic if RemoteAddr() is called after the connection to the client has been closed already. The current cache implementation doesn't create a new request+responsewriter during an asynchronous prefetch, but piggybacks on the request triggering the prefetch. This change copies the RemoteAddr first, so that it's safe to use it later during the actual prefetch request. A better implementation would be to completely decouple the prefetch request from the client triggering a request.
This commit is contained in:
		
				
					committed by
					
						 Miek Gieben
						Miek Gieben
					
				
			
			
				
	
			
			
			
						parent
						
							f78f30231d
						
					
				
				
					commit
					9c2dc7a156
				
			
							
								
								
									
										12
									
								
								plugin/cache/handler.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								plugin/cache/handler.go
									
									
									
									
										vendored
									
									
								
							| @@ -40,20 +40,18 @@ func (c *Cache) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) | ||||
|  | ||||
| 			threshold := int(math.Ceil(float64(c.percentage) / 100 * float64(i.origTTL))) | ||||
| 			if i.Freq.Hits() >= c.prefetch && ttl <= threshold { | ||||
| 				go func() { | ||||
| 				cw := newPrefetchResponseWriter(server, state, c) | ||||
| 				go func(w dns.ResponseWriter) { | ||||
| 					cachePrefetches.WithLabelValues(server).Inc() | ||||
| 					plugin.NextOrFailure(c.Name(), c.Next, ctx, w, r) | ||||
|  | ||||
| 					// When prefetching we loose the item i, and with it the frequency | ||||
| 					// that we've gathered sofar. See we copy the frequencies info back | ||||
| 					// into the new item that was stored in the cache. | ||||
| 					prr := &ResponseWriter{ResponseWriter: w, Cache: c, | ||||
| 						prefetch: true, state: state, | ||||
| 						server: server} | ||||
| 					plugin.NextOrFailure(c.Name(), c.Next, ctx, prr, r) | ||||
|  | ||||
| 					if i1 := c.exists(state); i1 != nil { | ||||
| 						i1.Freq.Reset(now, i.Freq.Hits()) | ||||
| 					} | ||||
| 				}() | ||||
| 				}(cw) | ||||
| 			} | ||||
| 		} | ||||
| 		return dns.RcodeSuccess, nil | ||||
|   | ||||
		Reference in New Issue
	
	Block a user