aboutsummaryrefslogtreecommitdiff
path: root/plugin/grpc/proxy.go
diff options
context:
space:
mode:
authorGravatar IƱigo <inigohu@gmail.com> 2019-03-14 08:12:28 +0100
committerGravatar Miek Gieben <miek@miek.nl> 2019-03-14 07:12:28 +0000
commit7b6cb76237d151ffa056c742ec281a17548fa089 (patch)
tree2100dd26d9e41f0be6fb365de9aeb334d7a94075 /plugin/grpc/proxy.go
parent0d8e1cf8b4ac157ef08837d0ff1e83597b8d1211 (diff)
downloadcoredns-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.go81
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
+}