mirror of
				https://github.com/coredns/coredns.git
				synced 2025-11-03 18:53:13 -05:00 
			
		
		
		
	* adds the dnstap I/O thread and should fix a lot of mistakes * docs * -race test * oops * docs
		
			
				
	
	
		
			60 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			60 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package out
 | 
						|
 | 
						|
import (
 | 
						|
	"net"
 | 
						|
	"time"
 | 
						|
 | 
						|
	fs "github.com/farsightsec/golang-framestream"
 | 
						|
)
 | 
						|
 | 
						|
// TCP is a Frame Streams encoder over TCP.
 | 
						|
type TCP struct {
 | 
						|
	address string
 | 
						|
	frames  [][]byte
 | 
						|
}
 | 
						|
 | 
						|
// NewTCP returns a TCP writer.
 | 
						|
func NewTCP(address string) *TCP {
 | 
						|
	s := &TCP{address: address}
 | 
						|
	s.frames = make([][]byte, 0, 13) // 13 messages buffer
 | 
						|
	return s
 | 
						|
}
 | 
						|
 | 
						|
// Write a single Frame Streams frame.
 | 
						|
func (s *TCP) Write(frame []byte) (n int, err error) {
 | 
						|
	s.frames = append(s.frames, frame)
 | 
						|
	if len(s.frames) == cap(s.frames) {
 | 
						|
		return len(frame), s.Flush()
 | 
						|
	}
 | 
						|
	return len(frame), nil
 | 
						|
}
 | 
						|
 | 
						|
// Flush the remaining frames.
 | 
						|
func (s *TCP) Flush() error {
 | 
						|
	defer func() {
 | 
						|
		s.frames = s.frames[:0]
 | 
						|
	}()
 | 
						|
	c, err := net.DialTimeout("tcp", s.address, time.Second)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	enc, err := fs.NewEncoder(c, &fs.EncoderOptions{
 | 
						|
		ContentType:   []byte("protobuf:dnstap.Dnstap"),
 | 
						|
		Bidirectional: true,
 | 
						|
	})
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	for _, frame := range s.frames {
 | 
						|
		if _, err = enc.Write(frame); err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return enc.Flush()
 | 
						|
}
 | 
						|
 | 
						|
// Close is an alias to Flush to satisfy io.WriteCloser similarly to type Socket.
 | 
						|
func (s *TCP) Close() error {
 | 
						|
	return s.Flush()
 | 
						|
}
 |