mirror of
				https://github.com/coredns/coredns.git
				synced 2025-11-03 18:53:13 -05:00 
			
		
		
		
	* WIP: Client-side of gRPC proxy * Add tests * gofmt * Implement OnShutdown; add a little logging * Update for context in Exchange change * go fmt * Update README * Review comments * Compiling is good * More README improvements
		
			
				
	
	
		
			78 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			78 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package proxy
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"crypto/tls"
 | 
						|
	"log"
 | 
						|
 | 
						|
	"github.com/miekg/coredns/middleware/proxy/pb"
 | 
						|
	"github.com/miekg/coredns/request"
 | 
						|
 | 
						|
	"github.com/miekg/dns"
 | 
						|
	"google.golang.org/grpc"
 | 
						|
	"google.golang.org/grpc/credentials"
 | 
						|
)
 | 
						|
 | 
						|
type grpcClient struct {
 | 
						|
	dialOpt  grpc.DialOption
 | 
						|
	clients  map[string]pb.DnsServiceClient
 | 
						|
	conns    []*grpc.ClientConn
 | 
						|
	upstream *staticUpstream
 | 
						|
}
 | 
						|
 | 
						|
func newGrpcClient(tls *tls.Config, u *staticUpstream) *grpcClient {
 | 
						|
	g := &grpcClient{upstream: u}
 | 
						|
 | 
						|
	if tls == nil {
 | 
						|
		g.dialOpt = grpc.WithInsecure()
 | 
						|
	} else {
 | 
						|
		g.dialOpt = grpc.WithTransportCredentials(credentials.NewTLS(tls))
 | 
						|
	}
 | 
						|
	g.clients = map[string]pb.DnsServiceClient{}
 | 
						|
 | 
						|
	return g
 | 
						|
}
 | 
						|
 | 
						|
func (g *grpcClient) Exchange(ctx context.Context, addr string, state request.Request) (*dns.Msg, error) {
 | 
						|
	msg, err := state.Req.Pack()
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	reply, err := g.clients[addr].Query(ctx, &pb.DnsPacket{Msg: msg})
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	d := new(dns.Msg)
 | 
						|
	err = d.Unpack(reply.Msg)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	return d, nil
 | 
						|
}
 | 
						|
 | 
						|
func (g *grpcClient) Protocol() string { return "grpc" }
 | 
						|
 | 
						|
func (g *grpcClient) OnShutdown(p *Proxy) error {
 | 
						|
	for i, conn := range g.conns {
 | 
						|
		err := conn.Close()
 | 
						|
		if err != nil {
 | 
						|
			log.Printf("[WARNING] Error closing connection %d: %s\n", i, err)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (g *grpcClient) OnStartup(p *Proxy) error {
 | 
						|
	for _, host := range g.upstream.Hosts {
 | 
						|
		conn, err := grpc.Dial(host.Name, g.dialOpt)
 | 
						|
		if err != nil {
 | 
						|
			log.Printf("[WARNING] Skipping gRPC host '%s' due to Dial error: %s\n", host.Name, err)
 | 
						|
		} else {
 | 
						|
			g.clients[host.Name] = pb.NewDnsServiceClient(conn)
 | 
						|
			g.conns = append(g.conns, conn)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 |