96 lines
2.6 KiB
Go
Raw Normal View History

// Copyright (c) HashiCorp, Inc.
[COMPLIANCE] License changes (#18443) * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Updating the license from MPL to Business Source License Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at <Blog URL>, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl. * add missing license headers * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
2023-08-11 09:12:13 -04:00
// SPDX-License-Identifier: BUSL-1.1
2022-09-29 21:19:51 -07:00
package dns
import (
"context"
"fmt"
agentdns "github.com/hashicorp/consul/agent/dns"
2022-09-29 21:19:51 -07:00
"net"
"github.com/hashicorp/go-hclog"
"github.com/miekg/dns"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/peer"
"google.golang.org/grpc/status"
"github.com/hashicorp/consul/proto-public/pbdns"
)
2022-09-30 14:51:12 -07:00
type LocalAddr struct {
2022-09-29 21:19:51 -07:00
IP net.IP
Port int
}
type Config struct {
2022-09-30 14:51:12 -07:00
Logger hclog.Logger
DNSServeMux *dns.ServeMux
LocalAddr LocalAddr
2022-09-29 21:19:51 -07:00
}
type Server struct {
Config
}
func NewServer(cfg Config) *Server {
return &Server{cfg}
}
func (s *Server) Register(registrar grpc.ServiceRegistrar) {
pbdns.RegisterDNSServiceServer(registrar, s)
2022-09-29 21:19:51 -07:00
}
2022-09-30 15:03:33 -07:00
// Query is a gRPC endpoint that will serve dns requests. It will be consumed primarily by the
// consul dataplane to proxy dns requests to consul.
2022-09-29 21:19:51 -07:00
func (s *Server) Query(ctx context.Context, req *pbdns.QueryRequest) (*pbdns.QueryResponse, error) {
pr, ok := peer.FromContext(ctx)
if !ok {
return nil, fmt.Errorf("error retrieving peer information from context")
}
var local net.Addr
var remote net.Addr
// We do this so that we switch to udp/tcp when handling the request since it will be proxied
2022-09-30 09:35:01 -07:00
// through consul through gRPC and we need to 'fake' the protocol so that the message is trimmed
// according to wether it is UDP or TCP.
2022-09-29 21:19:51 -07:00
switch req.GetProtocol() {
case pbdns.Protocol_PROTOCOL_TCP:
remote = pr.Addr
2022-09-30 14:51:12 -07:00
local = &net.TCPAddr{IP: s.LocalAddr.IP, Port: s.LocalAddr.Port}
2022-09-29 21:19:51 -07:00
case pbdns.Protocol_PROTOCOL_UDP:
remoteAddr := pr.Addr.(*net.TCPAddr)
remote = &net.UDPAddr{IP: remoteAddr.IP, Port: remoteAddr.Port}
2022-09-30 14:51:12 -07:00
local = &net.UDPAddr{IP: s.LocalAddr.IP, Port: s.LocalAddr.Port}
2022-09-29 21:19:51 -07:00
default:
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("error protocol type not set: %v", req.GetProtocol()))
}
reqCtx, err := agentdns.NewContextFromGRPCContext(ctx)
if err != nil {
s.Logger.Error("error parsing DNS context from grpc metadata", "err", err)
return nil, status.Error(codes.Internal, fmt.Sprintf("error parsing DNS context from grpc metadata: %s", err.Error()))
}
respWriter := &agentdns.BufferResponseWriter{
LocalAddress: local,
RemoteAddress: remote,
Logger: s.Logger,
RequestContext: reqCtx,
2022-09-29 21:19:51 -07:00
}
msg := &dns.Msg{}
err = msg.Unpack(req.Msg)
2022-09-29 21:19:51 -07:00
if err != nil {
s.Logger.Error("error unpacking message", "err", err)
return nil, status.Error(codes.Internal, fmt.Sprintf("failure decoding dns request: %s", err.Error()))
}
2022-09-29 21:19:51 -07:00
s.DNSServeMux.ServeDNS(respWriter, msg)
queryResponse := &pbdns.QueryResponse{Msg: respWriter.ResponseBuffer()}
2022-09-29 21:19:51 -07:00
return queryResponse, nil
}