From 489886de25e8831275b627fe12606c30bf0e36fb Mon Sep 17 00:00:00 2001 From: Avi Zimmerman Date: Sun, 30 Jul 2023 00:34:03 +0300 Subject: [PATCH] feat: advertise DNS services to peers --- pkg/cmd/nodecmd/global/global.go | 17 ++++++++++++++++- pkg/mesh/mesh_join.go | 1 + pkg/mesh/options_mesh.go | 5 +++++ pkg/meshdb/peers/peers.go | 7 ++----- pkg/net/inspect/inspect.go | 18 ------------------ pkg/services/node/server_join.go | 6 ++++++ 6 files changed, 30 insertions(+), 24 deletions(-) delete mode 100644 pkg/net/inspect/inspect.go diff --git a/pkg/cmd/nodecmd/global/global.go b/pkg/cmd/nodecmd/global/global.go index 4207ad282..e15c227f1 100644 --- a/pkg/cmd/nodecmd/global/global.go +++ b/pkg/cmd/nodecmd/global/global.go @@ -234,6 +234,8 @@ func (o *Options) Overlay(opts ...any) error { } } if primaryEndpoint.IsValid() { + // Determine the raft and wireguard ports so we can set our + // advertise addresses. var raftPort, wireguardPort uint16 for _, inOpts := range opts { if vopt, ok := inOpts.(*raft.Options); ok { @@ -321,7 +323,20 @@ func (o *Options) Overlay(opts ...any) error { v.TURN.PublicIP = primaryEndpoint.String() } } - + if v.MeshDNS.Enabled && v.MeshDNS.ListenUDP != "" && !o.DisableFeatureAdvertisement { + // Set the advertise DNS port + dnsAddr, err := netip.ParseAddrPort(v.MeshDNS.ListenUDP) + if err != nil { + return fmt.Errorf("failed to parse listen address: %w", err) + } + for _, inOpts := range opts { + if vopt, ok := inOpts.(*mesh.Options); ok { + if vopt.Mesh.DNSPort == 0 { + vopt.Mesh.DNSPort = int(dnsAddr.Port()) + } + } + } + } } } return nil diff --git a/pkg/mesh/mesh_join.go b/pkg/mesh/mesh_join.go index 43c9f4a00..20b44587b 100644 --- a/pkg/mesh/mesh_join.go +++ b/pkg/mesh/mesh_join.go @@ -137,6 +137,7 @@ func (s *meshStore) joinWithConn(ctx context.Context, c *grpc.ClientConn, featur PublicKey: key.PublicKey().String(), RaftPort: int32(s.raft.ListenPort()), GrpcPort: int32(s.opts.Mesh.GRPCPort), + MeshdnsPort: int32(s.opts.Mesh.DNSPort), PrimaryEndpoint: s.opts.Mesh.PrimaryEndpoint, WireguardEndpoints: s.opts.WireGuard.Endpoints, ZoneAwarenessId: s.opts.Mesh.ZoneAwarenessID, diff --git a/pkg/mesh/options_mesh.go b/pkg/mesh/options_mesh.go index c5d80b679..dd6ea48f9 100644 --- a/pkg/mesh/options_mesh.go +++ b/pkg/mesh/options_mesh.go @@ -33,6 +33,7 @@ const ( MaxJoinRetriesEnvVar = "MESH_MAX_JOIN_RETRIES" JoinTimeoutEnvVar = "MESH_JOIN_TIMEOUT" GRPCAdvertisePortEnvVar = "MESH_GRPC_PORT" + DNSAdvertisePortEnvVar = "MESH_DNS_PORT" PrimaryEndpointEnvVar = "MESH_PRIMARY_ENDPOINT" NodeRoutesEnvVar = "MESH_ROUTES" NodeDirectPeersEnvVar = "MESH_DIRECT_PEERS" @@ -64,6 +65,8 @@ type MeshOptions struct { DirectPeers []string `json:"direct-peers,omitempty" yaml:"direct-peers,omitempty" toml:"direct-peers,omitempty"` // GRPCPort is the port to advertise for gRPC. GRPCPort int `json:"grpc-port,omitempty" yaml:"grpc-port,omitempty" toml:"grpc-port,omitempty"` + // DNSPort is the port to advertise for DNS. + DNSPort int `json:"dns-port,omitempty" yaml:"dns-port,omitempty" toml:"dns-port,omitempty"` // NoIPv4 disables IPv4 usage. NoIPv4 bool `json:"no-ipv4,omitempty" yaml:"no-ipv4,omitempty" toml:"no-ipv4,omitempty"` // NoIPv6 disables IPv6 usage. @@ -121,6 +124,8 @@ func (o *MeshOptions) BindFlags(fl *flag.FlagSet) { "Join the cluster as a voter. Default behavior is to join as an observer.") fl.IntVar(&o.GRPCPort, "mesh.grpc-port", util.GetEnvIntDefault(GRPCAdvertisePortEnvVar, 8443), "GRPC advertise port.") + fl.IntVar(&o.DNSPort, "mesh.dns-port", util.GetEnvIntDefault(DNSAdvertisePortEnvVar, 0), + "DNS advertise port. This is set automatically when advertising is enabled and the mesh-dns server is running. Default is 0 (disabled).") fl.StringVar(&o.PrimaryEndpoint, "mesh.primary-endpoint", util.GetEnvDefault(PrimaryEndpointEnvVar, ""), `The primary endpoint to broadcast when joining a cluster. This is only necessary if the node intends on being publicly accessible.`) diff --git a/pkg/meshdb/peers/peers.go b/pkg/meshdb/peers/peers.go index b027f73fd..fe5d99408 100644 --- a/pkg/meshdb/peers/peers.go +++ b/pkg/meshdb/peers/peers.go @@ -314,11 +314,8 @@ func (p *peers) ListByFeature(ctx context.Context, feature v1.Feature) ([]Node, } out := make([]Node, 0) for _, node := range nodes { - for _, f := range node.Features { - if f == feature { - out = append(out, node) - break - } + if node.HasFeature(feature) { + out = append(out, node) } } return out, nil diff --git a/pkg/net/inspect/inspect.go b/pkg/net/inspect/inspect.go deleted file mode 100644 index 8a52d5316..000000000 --- a/pkg/net/inspect/inspect.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2023 Avi Zimmerman - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package inspect contains facilities for tapping into the network stack. -package inspect diff --git a/pkg/services/node/server_join.go b/pkg/services/node/server_join.go index 8b8d0e49c..8302adbb8 100644 --- a/pkg/services/node/server_join.go +++ b/pkg/services/node/server_join.go @@ -408,6 +408,9 @@ func (s *Server) Join(ctx context.Context, req *v1.JoinRequest) (*v1.JoinRespons log.Warn("could not lookup DNS servers", slog.String("error", err.Error())) } else { for _, peer := range dnsServers { + if peer.ID == req.GetId() { + continue + } switch { // Prefer the IPv4 address case peer.PrivateDNSAddrV4().IsValid(): @@ -437,6 +440,9 @@ func (s *Server) Join(ctx context.Context, req *v1.JoinRequest) (*v1.JoinRespons return nil, status.Errorf(codes.Internal, "failed to list peers by ICE feature: %v", err) } for _, peer := range peers { + if peer.ID == req.GetId() { + continue + } // We only return peers that are publicly accessible for now. // This should be configurable in the future. publicAddr := peer.PublicRPCAddr()