diff options
author | 2019-03-14 08:12:28 +0100 | |
---|---|---|
committer | 2019-03-14 07:12:28 +0000 | |
commit | 7b6cb76237d151ffa056c742ec281a17548fa089 (patch) | |
tree | 2100dd26d9e41f0be6fb365de9aeb334d7a94075 /plugin/grpc/proxy.go | |
parent | 0d8e1cf8b4ac157ef08837d0ff1e83597b8d1211 (diff) | |
download | coredns-7b6cb76237d151ffa056c742ec281a17548fa089.tar.gz coredns-7b6cb76237d151ffa056c742ec281a17548fa089.tar.zst coredns-7b6cb76237d151ffa056c742ec281a17548fa089.zip |
plugin/grpc: New gRPC plugin (#2667)
* plugin/grpc: New gRPC plugin
* some changes after the first review:
- remove healthcheck. gRPC already has this implicitly implemented
- some naming and stetic changes
- fix some comments
- other minor fixes
* plugin/grpc: New gRPC plugin
* some changes after the first review:
- remove healthcheck. gRPC already has this implicitly implemented
- some naming and stetic changes
- fix some comments
- other minor fixes
* add OWNERS file and change plugin order
* remove Rcode checker
Diffstat (limited to 'plugin/grpc/proxy.go')
-rw-r--r-- | plugin/grpc/proxy.go | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/plugin/grpc/proxy.go b/plugin/grpc/proxy.go new file mode 100644 index 000000000..f2bee95c0 --- /dev/null +++ b/plugin/grpc/proxy.go @@ -0,0 +1,81 @@ +package grpc + +import ( + "context" + "crypto/tls" + "strconv" + "time" + + "github.com/coredns/coredns/pb" + + "github.com/miekg/dns" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/status" +) + +// Proxy defines an upstream host. +type Proxy struct { + addr string + + // connection + client pb.DnsServiceClient + dialOpts []grpc.DialOption +} + +// newProxy returns a new proxy. +func newProxy(addr string, tlsConfig *tls.Config) (*Proxy, error) { + p := &Proxy{ + addr: addr, + } + + if tlsConfig != nil { + p.dialOpts = append(p.dialOpts, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig))) + } else { + p.dialOpts = append(p.dialOpts, grpc.WithInsecure()) + } + + conn, err := grpc.Dial(p.addr, p.dialOpts...) + if err != nil { + return nil, err + } + p.client = pb.NewDnsServiceClient(conn) + + return p, nil +} + +// query sends the request and waits for a response. +func (p *Proxy) query(ctx context.Context, req *dns.Msg) (*dns.Msg, error) { + start := time.Now() + + msg, err := req.Pack() + if err != nil { + return nil, err + } + + reply, err := p.client.Query(ctx, &pb.DnsPacket{Msg: msg}) + if err != nil { + // if not found message, return empty message with NXDomain code + if status.Code(err) == codes.NotFound { + m := new(dns.Msg).SetRcode(req, dns.RcodeNameError) + return m, nil + } + return nil, err + } + ret := new(dns.Msg) + if err := ret.Unpack(reply.Msg); err != nil { + return nil, err + } + + rc, ok := dns.RcodeToString[ret.Rcode] + if !ok { + rc = strconv.Itoa(ret.Rcode) + } + + RequestCount.WithLabelValues(p.addr).Add(1) + RcodeCount.WithLabelValues(rc, p.addr).Add(1) + RequestDuration.WithLabelValues(p.addr).Observe(time.Since(start).Seconds()) + + return ret, nil +} |