mirror of
				https://github.com/coredns/coredns.git
				synced 2025-11-04 03:03:14 -05:00 
			
		
		
		
	Fixed dnstap panic after graceful restart (send on closed channel) (#1479)
This commit is contained in:
		
				
					committed by
					
						
						Miek Gieben
					
				
			
			
				
	
			
			
			
						parent
						
							b93a36b213
						
					
				
				
					commit
					3fb07161b7
				
			@@ -24,6 +24,7 @@ type dnstapIO struct {
 | 
				
			|||||||
	enc      *dnstapEncoder
 | 
						enc      *dnstapEncoder
 | 
				
			||||||
	queue    chan tap.Dnstap
 | 
						queue    chan tap.Dnstap
 | 
				
			||||||
	dropped  uint32
 | 
						dropped  uint32
 | 
				
			||||||
 | 
						quit     chan struct{}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// New returns a new and initialized DnstapIO.
 | 
					// New returns a new and initialized DnstapIO.
 | 
				
			||||||
@@ -36,6 +37,7 @@ func New(endpoint string, socket bool) DnstapIO {
 | 
				
			|||||||
			Bidirectional: true,
 | 
								Bidirectional: true,
 | 
				
			||||||
		}),
 | 
							}),
 | 
				
			||||||
		queue: make(chan tap.Dnstap, queueSize),
 | 
							queue: make(chan tap.Dnstap, queueSize),
 | 
				
			||||||
 | 
							quit:  make(chan struct{}),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -92,7 +94,7 @@ func (dio *dnstapIO) closeConnection() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Close waits until the I/O routine is finished to return.
 | 
					// Close waits until the I/O routine is finished to return.
 | 
				
			||||||
func (dio *dnstapIO) Close() {
 | 
					func (dio *dnstapIO) Close() {
 | 
				
			||||||
	close(dio.queue)
 | 
						close(dio.quit)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (dio *dnstapIO) flushBuffer() {
 | 
					func (dio *dnstapIO) flushBuffer() {
 | 
				
			||||||
@@ -124,12 +126,11 @@ func (dio *dnstapIO) serve() {
 | 
				
			|||||||
	timeout := time.After(flushTimeout)
 | 
						timeout := time.After(flushTimeout)
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
		case payload, ok := <-dio.queue:
 | 
							case <-dio.quit:
 | 
				
			||||||
			if !ok {
 | 
					 | 
				
			||||||
			dio.flushBuffer()
 | 
								dio.flushBuffer()
 | 
				
			||||||
			dio.closeConnection()
 | 
								dio.closeConnection()
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
			}
 | 
							case payload := <-dio.queue:
 | 
				
			||||||
			dio.write(&payload)
 | 
								dio.write(&payload)
 | 
				
			||||||
		case <-timeout:
 | 
							case <-timeout:
 | 
				
			||||||
			if dropped := atomic.SwapUint32(&dio.dropped, 0); dropped > 0 {
 | 
								if dropped := atomic.SwapUint32(&dio.dropped, 0); dropped > 0 {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user