From 3bc8aca5f2f1798a090cc4b5731cbd17ae42b3de Mon Sep 17 00:00:00 2001 From: Dmitriy Matrenichev Date: Tue, 29 Oct 2024 22:00:44 +0300 Subject: [PATCH] feat: support conditional start of IPv6 dns servers This PR does those things: - [x] Refactored `DNSResolveCacheController`. Most of the logic moved to `dns` package types. Simplify and streamline logic. - [x] Replace most of the goroutine orchestration with suture package. - [x] Support per-item reaction to the dns listeners/servers failing to start. This allows us to ignore IPv6 errors if it's disabled. - [x] Support per-item reaction to the dns listeners/servers failing to stop. - [ ] Raise IPv6 listener on link-local address for dns (both TCP and UDP). - [ ] Update kubelet's `resolv.conf` IPv4/IPv6 endpoints. Closes #9384 Signed-off-by: Dmitriy Matrenichev --- .../definitions/network/network.proto | 1 + go.mod | 1 + go.sum | 2 + .../controllers/network/address_spec_test.go | 42 + .../controllers/network/dns_resolve_cache.go | 350 ++--- .../network/dns_resolve_cache_test.go | 1 + .../pkg/controllers/network/etcfile.go | 11 +- .../pkg/controllers/network/etcfile_test.go | 12 +- .../pkg/controllers/network/hostdns_config.go | 96 +- .../network/nftables_chain_config.go | 22 +- .../app/machined/pkg/xcontext/xcontext.go | 28 + internal/pkg/dns/dns.go | 102 +- internal/pkg/dns/dns_test.go | 169 ++- internal/pkg/dns/manager.go | 318 ++++ internal/pkg/dns/runnner.go | 108 ++ .../definitions/network/network.pb.go | 1281 +++++++++-------- .../definitions/network/network_vtproto.pb.go | 76 + pkg/machinery/constants/constants.go | 5 + .../resources/network/hostdns_config.go | 9 +- website/content/v1.9/reference/api.md | 1 + 20 files changed, 1556 insertions(+), 1079 deletions(-) create mode 100644 internal/app/machined/pkg/xcontext/xcontext.go create mode 100644 internal/pkg/dns/manager.go create mode 100644 internal/pkg/dns/runnner.go diff --git a/api/resource/definitions/network/network.proto b/api/resource/definitions/network/network.proto index 9ee2bf2d819..60f9e6a3c75 100755 --- a/api/resource/definitions/network/network.proto +++ b/api/resource/definitions/network/network.proto @@ -114,6 +114,7 @@ message HostDNSConfigSpec { repeated common.NetIPPort listen_addresses = 2; common.NetIP service_host_dns_address = 3; bool resolve_member_names = 4; + common.NetIP service_host_dns_address_v6 = 5; } // HostnameSpecSpec describes node hostname. diff --git a/go.mod b/go.mod index 037123fff67..a39ffed2ec7 100644 --- a/go.mod +++ b/go.mod @@ -171,6 +171,7 @@ require ( github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 + github.com/thejerf/suture/v4 v4.0.5 github.com/u-root/u-root v0.14.0 github.com/ulikunitz/xz v0.5.12 github.com/vmware/vmw-guestinfo v0.0.0-20220317130741-510905f0efa3 diff --git a/go.sum b/go.sum index 8be3bebe5c5..0a140339c48 100644 --- a/go.sum +++ b/go.sum @@ -732,6 +732,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/thejerf/suture/v4 v4.0.5 h1:F1E/4FZwXWqvlWDKEUo6/ndLtxGAUzMmNqkrMknZbAA= +github.com/thejerf/suture/v4 v4.0.5/go.mod h1:gu9Y4dXNUWFrByqRt30Rm9/UZ0wzRSt9AJS6xu/ZGxU= github.com/u-root/u-root v0.14.0 h1:Ka4T10EEML7dQ5XDvO9c3MBN8z4nuSnGjcd1jmU2ivg= github.com/u-root/u-root v0.14.0/go.mod h1:hAyZorapJe4qzbLWlAkmSVCJGbfoU9Pu4jpJ1WMluqE= github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 h1:pyC9PaHYZFgEKFdlp3G8RaCKgVpHZnecvArXvPXcFkM= diff --git a/internal/app/machined/pkg/controllers/network/address_spec_test.go b/internal/app/machined/pkg/controllers/network/address_spec_test.go index bc17519e3e7..453942d63f6 100644 --- a/internal/app/machined/pkg/controllers/network/address_spec_test.go +++ b/internal/app/machined/pkg/controllers/network/address_spec_test.go @@ -28,6 +28,7 @@ import ( "golang.org/x/sys/unix" netctrl "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/network" + "github.com/siderolabs/talos/pkg/machinery/constants" "github.com/siderolabs/talos/pkg/machinery/nethelpers" "github.com/siderolabs/talos/pkg/machinery/resources/network" ) @@ -170,6 +171,47 @@ func (suite *AddressSpecSuite) TestLoopback() { suite.Require().NoError(suite.state.Destroy(suite.ctx, loopback.Metadata())) } +func (suite *AddressSpecSuite) TestIPV6ULA() { + loopback := network.NewAddressSpec(network.NamespaceName, "lo/"+constants.HostDNSAddressV6+"/128") + *loopback.TypedSpec() = network.AddressSpecSpec{ + Address: netip.MustParsePrefix(constants.HostDNSAddressV6 + "/128"), + LinkName: "lo", + Family: nethelpers.FamilyInet6, + Scope: nethelpers.ScopeGlobal, + ConfigLayer: network.ConfigDefault, + Flags: nethelpers.AddressFlags(nethelpers.AddressPermanent), + } + + for _, res := range []resource.Resource{loopback} { + suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec()) + } + + suite.Assert().NoError( + retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry( + func() error { + return suite.assertLinkAddress("lo", constants.HostDNSAddressV6+"/128") + }, + ), + ) + + // teardown the address + for { + ready, err := suite.state.Teardown(suite.ctx, loopback.Metadata()) + suite.Require().NoError(err) + + if ready { + break + } + + time.Sleep(100 * time.Millisecond) + } + + // torn down address should be removed immediately + suite.Assert().NoError(suite.assertNoLinkAddress("lo", constants.HostDNSAddressV6+"/128")) + + suite.Require().NoError(suite.state.Destroy(suite.ctx, loopback.Metadata())) +} + func (suite *AddressSpecSuite) TestDummy() { dummyInterface := suite.uniqueDummyInterface() diff --git a/internal/app/machined/pkg/controllers/network/dns_resolve_cache.go b/internal/app/machined/pkg/controllers/network/dns_resolve_cache.go index 98210340ba7..265f28bc6a3 100644 --- a/internal/app/machined/pkg/controllers/network/dns_resolve_cache.go +++ b/internal/app/machined/pkg/controllers/network/dns_resolve_cache.go @@ -5,24 +5,20 @@ package network import ( + "cmp" "context" - "errors" "fmt" - "net" + "iter" "net/netip" - "slices" - "strings" "sync" - "time" "github.com/coredns/coredns/plugin/pkg/proxy" "github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/safe" "github.com/cosi-project/runtime/pkg/state" - dnssrv "github.com/miekg/dns" "github.com/siderolabs/gen/optional" - "github.com/siderolabs/gen/pair" "github.com/siderolabs/gen/xiter" + "github.com/thejerf/suture/v4" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -36,13 +32,9 @@ type DNSResolveCacheController struct { State state.State Logger *zap.Logger - mx sync.Mutex - handler *dns.Handler - nodeHandler *dns.NodeHandler - rootHandler dnssrv.Handler - runners map[runnerConfig]pair.Pair[func(), <-chan struct{}] - reconcile chan struct{} - originalCtx context.Context //nolint:containedctx + mx sync.Mutex + manager *dns.Manager + reconcile chan struct{} } // Name implements controller.Controller interface. @@ -74,15 +66,21 @@ func (ctrl *DNSResolveCacheController) Outputs() []controller.Output { } // Run implements controller.Controller interface. -// -//nolint:gocyclo,cyclop -func (ctrl *DNSResolveCacheController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { +func (ctrl *DNSResolveCacheController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error { ctrl.init(ctx) ctrl.mx.Lock() defer ctrl.mx.Unlock() - defer ctrl.stopRunners(ctx, false) + defer func() { + if err := ctrl.manager.ClearAll(ctx.Err() == nil); err != nil { + ctrl.Logger.Error("error stopping dns runners", zap.Error(err)) + } + + if ctx.Err() != nil { + ctrl.Logger.Info("manager finished", zap.Error(<-ctrl.manager.Done())) + } + }() for { select { @@ -90,264 +88,128 @@ func (ctrl *DNSResolveCacheController) Run(ctx context.Context, r controller.Run return nil case <-r.EventCh(): case <-ctrl.reconcile: - for cfg, stop := range ctrl.runners { - select { - default: - continue - case <-stop.F2: - } - - stop.F1() - delete(ctrl.runners, cfg) - } } - cfg, err := safe.ReaderGetByID[*network.HostDNSConfig](ctx, r, network.HostDNSConfigID) - if err != nil { - if state.IsNotFoundError(err) { - continue - } - - return fmt.Errorf("error getting host dns config: %w", err) - } - - r.StartTrackingOutputs() - - if !cfg.TypedSpec().Enabled { - ctrl.stopRunners(ctx, true) - - if err = safe.CleanupOutputs[*network.DNSResolveCache](ctx, r); err != nil { - return fmt.Errorf("error cleaning up dns status on disable: %w", err) - } - - continue - } - - ctrl.nodeHandler.SetEnabled(cfg.TypedSpec().ResolveMemberNames) - - touchedRunners := make(map[runnerConfig]struct{}, len(ctrl.runners)) - - for _, addr := range cfg.TypedSpec().ListenAddresses { - for _, netwk := range []string{"udp", "tcp"} { - runnerCfg := runnerConfig{net: netwk, addr: addr} - - if _, ok := ctrl.runners[runnerCfg]; !ok { - runner, rErr := newDNSRunner(runnerCfg, ctrl.rootHandler, ctrl.Logger, cfg.TypedSpec().ServiceHostDNSAddress.IsValid()) - if rErr != nil { - return fmt.Errorf("error creating dns runner: %w", rErr) - } - - ctrl.runners[runnerCfg] = pair.MakePair(runner.Start(ctrl.handleDone(ctx, logger))) - } - - if err = ctrl.writeDNSStatus(ctx, r, runnerCfg); err != nil { - return fmt.Errorf("error writing dns status: %w", err) - } - - touchedRunners[runnerCfg] = struct{}{} - } - } - - for runnerCfg, stop := range ctrl.runners { - if _, ok := touchedRunners[runnerCfg]; !ok { - stop.F1() - delete(ctrl.runners, runnerCfg) - - continue - } - } - - upstreams, err := safe.ReaderListAll[*network.DNSUpstream](ctx, r) - if err != nil { - return fmt.Errorf("error getting resolver status: %w", err) - } - - prxs := xiter.Map( - // We are using iterator here to preserve finalizer on - func(upstream *network.DNSUpstream) *proxy.Proxy { - return upstream.TypedSpec().Value.Conn.Proxy().(*proxy.Proxy) - }, - upstreams.All(), - ) - - if ctrl.handler.SetProxy(prxs) { - ctrl.Logger.Info("updated dns server nameservers", zap.Array("addrs", addrsArr(upstreams))) - } - - if err = safe.CleanupOutputs[*network.DNSResolveCache](ctx, r); err != nil { - return fmt.Errorf("error cleaning up dns status: %w", err) + if err := ctrl.run(ctx, r); err != nil { + return err } } } -func (ctrl *DNSResolveCacheController) writeDNSStatus(ctx context.Context, r controller.Runtime, config runnerConfig) error { - return safe.WriterModify(ctx, r, network.NewDNSResolveCache(fmt.Sprintf("%s-%s", config.net, config.addr)), func(drc *network.DNSResolveCache) error { - drc.TypedSpec().Status = "running" - - return nil - }) -} +//nolint:gocyclo +func (ctrl *DNSResolveCacheController) run(ctx context.Context, r controller.Runtime) (resErr error) { + r.StartTrackingOutputs() + defer cleanupOutputs(ctx, r, &resErr) -func (ctrl *DNSResolveCacheController) init(ctx context.Context) { - if ctrl.runners != nil { - if ctrl.originalCtx != ctx { - // This should not happen, but if it does, it's a bug. - panic("DNSResolveCacheController is called with a different context") - } + cfg, err := safe.ReaderGetByID[*network.HostDNSConfig](ctx, r, network.HostDNSConfigID) - return + switch { + case state.IsNotFoundError(err): + return nil + case err != nil: + return fmt.Errorf("error getting host dns config: %w", err) } - ctrl.originalCtx = ctx - ctrl.handler = dns.NewHandler(ctrl.Logger) - ctrl.nodeHandler = dns.NewNodeHandler(ctrl.handler, &stateMapper{state: ctrl.State}, ctrl.Logger) - ctrl.rootHandler = dns.NewCache(ctrl.nodeHandler, ctrl.Logger) - ctrl.runners = map[runnerConfig]pair.Pair[func(), <-chan struct{}]{} - ctrl.reconcile = make(chan struct{}, 1) - - // Ensure we stop all runners when the context is canceled, no matter where we are currently. - // For example if we are in Controller runtime sleeping after error and ctx is canceled, we should stop all runners - // but, we will never call Run method again, so we need to ensure this happens regardless of the current state. - context.AfterFunc(ctx, func() { - ctrl.mx.Lock() - defer ctrl.mx.Unlock() - - ctrl.stopRunners(ctx, true) - }) -} - -func (ctrl *DNSResolveCacheController) stopRunners(ctx context.Context, ignoreCtx bool) { - if !ignoreCtx && ctx.Err() == nil { - // context not yet canceled, preserve runners, cache and handler - return - } + ctrl.manager.AllowNodeResolving(cfg.TypedSpec().ResolveMemberNames) - for _, stop := range ctrl.runners { - stop.F1() + if !cfg.TypedSpec().Enabled { + return ctrl.manager.ClearAll(false) } - clear(ctrl.runners) - - ctrl.handler.Stop() -} + pairs := allAddressPairs(cfg.TypedSpec().ListenAddresses) + forwardKubeDNSToHost := cfg.TypedSpec().ServiceHostDNSAddress.IsValid() || cfg.TypedSpec().ServiceHostDNSAddressV6.IsValid() -func (ctrl *DNSResolveCacheController) handleDone(ctx context.Context, logger *zap.Logger) func(err error) { - return func(err error) { - if ctx.Err() != nil { - if err != nil && !errors.Is(err, net.ErrClosed) { - logger.Error("controller is closing, but error running dns server", zap.Error(err)) - } - - return - } - - if err != nil { - logger.Error("error running dns server", zap.Error(err)) + for runCfg, runErr := range ctrl.manager.RunAll(pairs, forwardKubeDNSToHost) { + switch { + case runErr != nil && (runCfg.Network == "tcp6" || runCfg.Network == "udp6"): + // Ignore ipv6 errors + ctrl.Logger.Warn("ignoring ipv6 dns runner error", zap.Error(runErr)) + case runErr != nil: + return fmt.Errorf("error updating dns runner '%v': %w", runCfg, runErr) + case runCfg.Status == dns.StatusRemoved: + // Removed runned, no reason to update status + continue } - select { - case ctrl.reconcile <- struct{}{}: - default: + if err = ctrl.writeDNSStatus(ctx, r, runCfg.AddressPair); err != nil { + return fmt.Errorf("error writing dns status: %w", err) } } -} - -type runnerConfig struct { - net string - addr netip.AddrPort -} -func newDNSRunner(cfg runnerConfig, rootHandler dnssrv.Handler, logger *zap.Logger, forwardEnabled bool) (*dns.Server, error) { - if cfg.addr.Addr().Is6() { - cfg.net += "6" - } - - logger = logger.With(zap.String("net", cfg.net), zap.Stringer("addr", cfg.addr)) - - var serverOpts dns.ServerOptions - - controlFn, ctrlErr := dns.MakeControl(cfg.net, forwardEnabled) - if ctrlErr != nil { - return nil, fmt.Errorf("error creating %q control function: %w", cfg.net, ctrlErr) + upstreams, err := safe.ReaderListAll[*network.DNSUpstream](ctx, r) + if err != nil { + return fmt.Errorf("error getting resolver status: %w", err) } - switch cfg.net { - case "udp", "udp6": - packetConn, err := dns.NewUDPPacketConn(cfg.net, cfg.addr.String(), controlFn) - if err != nil { - return nil, fmt.Errorf("error creating %q packet conn: %w", cfg.net, err) - } - - serverOpts = dns.ServerOptions{ - PacketConn: packetConn, - Handler: rootHandler, - Logger: logger, - } - - case "tcp", "tcp6": - listener, err := dns.NewTCPListener(cfg.net, cfg.addr.String(), controlFn) - if err != nil { - return nil, fmt.Errorf("error creating %q listener: %w", cfg.net, err) - } + prxs := xiter.Map( + // We are using iterator here to preserve finalizer on + func(upstream *network.DNSUpstream) *proxy.Proxy { + return upstream.TypedSpec().Value.Conn.Proxy().(*proxy.Proxy) + }, + upstreams.All(), + ) - serverOpts = dns.ServerOptions{ - Listener: listener, - Handler: rootHandler, - ReadTimeout: 3 * time.Second, - WriteTimeout: 5 * time.Second, - IdleTimeout: func() time.Duration { return 10 * time.Second }, - MaxTCPQueries: -1, - Logger: logger, - } + if ctrl.manager.SetUpstreams(prxs) { + ctrl.Logger.Info("updated dns server nameservers", zap.Array("addrs", addrsArr(upstreams))) } - return dns.NewServer(serverOpts), nil + return nil } -type stateMapper struct { - state state.State +func cleanupOutputs(ctx context.Context, r controller.Runtime, resErr *error) { + if err := safe.CleanupOutputs[*network.DNSResolveCache](ctx, r); err != nil { + *resErr = cmp.Or(*resErr, fmt.Errorf("error cleaning up dns resolve cache: %w", err)) + } } -func (s *stateMapper) ResolveAddr(ctx context.Context, qType uint16, name string) []netip.Addr { - name = strings.TrimRight(name, ".") +func (ctrl *DNSResolveCacheController) writeDNSStatus(ctx context.Context, r controller.Runtime, config dns.AddressPair) error { + res := network.NewDNSResolveCache(fmt.Sprintf("%s-%s", config.Network, config.Addr)) - list, err := safe.ReaderListAll[*cluster.Member](ctx, s.state) - if err != nil { - return nil - } + return safe.WriterModify(ctx, r, res, func(drc *network.DNSResolveCache) error { + drc.TypedSpec().Status = "running" - elem, ok := list.Find(func(res *cluster.Member) bool { - return fqdnMatch(name, res.TypedSpec().Hostname) || fqdnMatch(name, res.Metadata().ID()) - }) - if !ok { return nil - } - - result := slices.DeleteFunc(slices.Clone(elem.TypedSpec().Addresses), func(addr netip.Addr) bool { - return !((qType == dnssrv.TypeA && addr.Is4()) || (qType == dnssrv.TypeAAAA && addr.Is6())) }) +} - if len(result) == 0 { - return nil +func (ctrl *DNSResolveCacheController) init(ctx context.Context) { + if ctrl.manager == nil { + ctrl.manager = dns.NewManager(&memberReader{st: ctrl.State}, ctrl.eventHook, ctrl.Logger) + + // Ensure we stop all runners when the context is canceled, no matter where we are currently. + // For example if we are in Controller runtime sleeping after error and ctx is canceled, we should stop all runners + // but, we will never call Run method again, so we need to ensure this happens regardless of the current state. + context.AfterFunc(ctx, func() { + ctrl.mx.Lock() + defer ctrl.mx.Unlock() + + if err := ctrl.manager.ClearAll(false); err != nil { + ctrl.Logger.Error("error ctx stopping dns runners", zap.Error(err)) + } + }) } - return result + ctrl.manager.ServeBackground(ctx) } -func fqdnMatch(what, where string) bool { - what = strings.TrimRight(what, ".") - where = strings.TrimRight(where, ".") +func (ctrl *DNSResolveCacheController) eventHook(event suture.Event) { + ctrl.Logger.Info("dns-resolve-cache-runners event", zap.String("event", event.String())) - if what == where { - return true + select { + case ctrl.reconcile <- struct{}{}: + default: } +} + +type memberReader struct{ st state.State } - first, _, found := strings.Cut(where, ".") - if !found { - return false +func (m *memberReader) ReadMembers(ctx context.Context) (iter.Seq[*cluster.Member], error) { + list, err := safe.ReaderListAll[*cluster.Member](ctx, m.st) + if err != nil { + return nil, err } - return what == first + return list.All(), nil } type addrsArr safe.List[*network.DNSUpstream] @@ -361,3 +223,23 @@ func (a addrsArr) MarshalLogArray(encoder zapcore.ArrayEncoder) error { return nil } + +func allAddressPairs(addresses []netip.AddrPort) iter.Seq[dns.AddressPair] { + return func(yield func(dns.AddressPair) bool) { + for _, addr := range addresses { + networks := [...]string{"udp", "tcp"} + if addr.Addr().Is6() { + networks = [...]string{"udp6", "tcp6"} + } + + for _, netwk := range networks { + if !yield(dns.AddressPair{ + Network: netwk, + Addr: addr, + }) { + return + } + } + } + } +} diff --git a/internal/app/machined/pkg/controllers/network/dns_resolve_cache_test.go b/internal/app/machined/pkg/controllers/network/dns_resolve_cache_test.go index bc71657701f..e183db994d8 100644 --- a/internal/app/machined/pkg/controllers/network/dns_resolve_cache_test.go +++ b/internal/app/machined/pkg/controllers/network/dns_resolve_cache_test.go @@ -285,6 +285,7 @@ func getDynamicPort() (string, error) { func makeAddrs(port string) []netip.AddrPort { return []netip.AddrPort{ netip.MustParseAddrPort("127.0.0.53:" + port), + netip.MustParseAddrPort("[::1]:" + port), } } diff --git a/internal/app/machined/pkg/controllers/network/etcfile.go b/internal/app/machined/pkg/controllers/network/etcfile.go index 60c5a863b58..fe864a28059 100644 --- a/internal/app/machined/pkg/controllers/network/etcfile.go +++ b/internal/app/machined/pkg/controllers/network/etcfile.go @@ -20,8 +20,8 @@ import ( "github.com/cosi-project/runtime/pkg/safe" "github.com/cosi-project/runtime/pkg/state" "github.com/siderolabs/gen/optional" - "github.com/siderolabs/gen/value" "github.com/siderolabs/gen/xiter" + "github.com/siderolabs/gen/xslices" "go.uber.org/zap" efiles "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/files" @@ -158,10 +158,13 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, _ } if resolverStatus != nil && hostDNSCfg != nil { - dnsServers := resolverStatus.TypedSpec().DNSServers + dnsServers := xslices.FilterInPlace( + []netip.Addr{hostDNSCfg.TypedSpec().ServiceHostDNSAddress, hostDNSCfg.TypedSpec().ServiceHostDNSAddressV6}, + netip.Addr.IsValid, + ) - if !value.IsZero(hostDNSCfg.TypedSpec().ServiceHostDNSAddress) { - dnsServers = []netip.Addr{hostDNSCfg.TypedSpec().ServiceHostDNSAddress} + if len(dnsServers) == 0 { + dnsServers = resolverStatus.TypedSpec().DNSServers } conf := renderResolvConf(slices.All(dnsServers), hostnameStatusSpec, cfgProvider) diff --git a/internal/app/machined/pkg/controllers/network/etcfile_test.go b/internal/app/machined/pkg/controllers/network/etcfile_test.go index c6b849d222e..a4ffa06f414 100644 --- a/internal/app/machined/pkg/controllers/network/etcfile_test.go +++ b/internal/app/machined/pkg/controllers/network/etcfile_test.go @@ -128,8 +128,10 @@ func (suite *EtcFileConfigSuite) SetupTest() { suite.hostDNSConfig.TypedSpec().ListenAddresses = []netip.AddrPort{ netip.MustParseAddrPort("127.0.0.53:53"), netip.MustParseAddrPort("169.254.116.108:53"), + netip.MustParseAddrPort("[fd54:616c:6f73::204f:5320:444e:531]:53"), } suite.hostDNSConfig.TypedSpec().ServiceHostDNSAddress = netip.MustParseAddr("169.254.116.108") + suite.hostDNSConfig.TypedSpec().ServiceHostDNSAddressV6 = netip.MustParseAddr("fd54:616c:6f73::204f:5320:444e:531") } func (suite *EtcFileConfigSuite) startRuntime() { @@ -228,7 +230,7 @@ func (suite *EtcFileConfigSuite) TestComplete() { etcFileContents{ hosts: "127.0.0.1 localhost\n33.11.22.44 foo.example.com foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n10.0.0.1 a b\n10.0.0.2 c d\n", //nolint:lll resolvConf: "nameserver 127.0.0.53\n\nsearch example.com\n", - resolvGlobalConf: "nameserver 169.254.116.108\n\nsearch example.com\n", + resolvGlobalConf: "nameserver 169.254.116.108\nnameserver fd54:616c:6f73:0:204f:5320:444e:531\n\nsearch example.com\n", }, ) } @@ -239,7 +241,7 @@ func (suite *EtcFileConfigSuite) TestNoExtraHosts() { etcFileContents{ hosts: "127.0.0.1 localhost\n33.11.22.44 foo.example.com foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n", resolvConf: "nameserver 127.0.0.53\n\nsearch example.com\n", - resolvGlobalConf: "nameserver 169.254.116.108\n\nsearch example.com\n", + resolvGlobalConf: "nameserver 169.254.116.108\nnameserver fd54:616c:6f73:0:204f:5320:444e:531\n\nsearch example.com\n", }, ) } @@ -262,7 +264,7 @@ func (suite *EtcFileConfigSuite) TestNoSearchDomain() { etcFileContents{ hosts: "127.0.0.1 localhost\n33.11.22.44 foo.example.com foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n", resolvConf: "nameserver 127.0.0.53\n", - resolvGlobalConf: "nameserver 169.254.116.108\n", + resolvGlobalConf: "nameserver 169.254.116.108\nnameserver fd54:616c:6f73:0:204f:5320:444e:531\n", }, ) } @@ -275,7 +277,7 @@ func (suite *EtcFileConfigSuite) TestNoDomainname() { etcFileContents{ hosts: "127.0.0.1 localhost\n33.11.22.44 foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n", resolvConf: "nameserver 127.0.0.53\n", - resolvGlobalConf: "nameserver 169.254.116.108\n", + resolvGlobalConf: "nameserver 169.254.116.108\nnameserver fd54:616c:6f73:0:204f:5320:444e:531\n", }, ) } @@ -286,7 +288,7 @@ func (suite *EtcFileConfigSuite) TestOnlyResolvers() { etcFileContents{ hosts: "", resolvConf: "nameserver 127.0.0.53\n", - resolvGlobalConf: "nameserver 169.254.116.108\n", + resolvGlobalConf: "nameserver 169.254.116.108\nnameserver fd54:616c:6f73:0:204f:5320:444e:531\n", }, ) } diff --git a/internal/app/machined/pkg/controllers/network/hostdns_config.go b/internal/app/machined/pkg/controllers/network/hostdns_config.go index 4fad1d70a1d..6600cc5d5fb 100644 --- a/internal/app/machined/pkg/controllers/network/hostdns_config.go +++ b/internal/app/machined/pkg/controllers/network/hostdns_config.go @@ -8,13 +8,12 @@ import ( "context" "fmt" "net/netip" + "slices" "github.com/cosi-project/runtime/pkg/controller" - "github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/safe" "github.com/cosi-project/runtime/pkg/state" "github.com/siderolabs/gen/optional" - "github.com/siderolabs/gen/value" "github.com/siderolabs/go-procfs/procfs" "go.uber.org/zap" @@ -74,6 +73,8 @@ func (ctrl *HostDNSConfigController) Run(ctx context.Context, r controller.Runti var cfgProvider talosconfig.Config + r.StartTrackingOutputs() + cfg, err := safe.ReaderGetByID[*config.MachineConfig](ctx, r, config.V1Alpha1ID) if err != nil { if !state.IsNotFoundError(err) { @@ -83,7 +84,7 @@ func (ctrl *HostDNSConfigController) Run(ctx context.Context, r controller.Runti cfgProvider = cfg.Config() } - var newServiceAddr netip.Addr + newServiceAddrs := make([]netip.Addr, 0, 2) if err := safe.WriterModify(ctx, r, network.NewHostDNSConfig(network.HostDNSConfigID), func(res *network.HostDNSConfig) error { res.TypedSpec().ListenAddresses = []netip.AddrPort{ @@ -91,6 +92,7 @@ func (ctrl *HostDNSConfigController) Run(ctx context.Context, r controller.Runti } res.TypedSpec().ServiceHostDNSAddress = netip.Addr{} + res.TypedSpec().ServiceHostDNSAddressV6 = netip.Addr{} if cfgProvider == nil { res.TypedSpec().Enabled = false @@ -101,11 +103,30 @@ func (ctrl *HostDNSConfigController) Run(ctx context.Context, r controller.Runti res.TypedSpec().Enabled = cfgProvider.Machine().Features().HostDNS().Enabled() res.TypedSpec().ResolveMemberNames = cfgProvider.Machine().Features().HostDNS().ResolveMemberNames() - if cfgProvider.Machine().Features().HostDNS().ForwardKubeDNSToHost() { - newServiceAddr = netip.MustParseAddr(constants.HostDNSAddress) + if !cfgProvider.Machine().Features().HostDNS().ForwardKubeDNSToHost() { + return nil + } + + if slices.ContainsFunc( + cfgProvider.Cluster().Network().PodCIDRs(), + func(cidr string) bool { return netip.MustParsePrefix(cidr).Addr().Is4() }, + ) { + parsed := netip.MustParseAddr(constants.HostDNSAddress) + newServiceAddrs = append(newServiceAddrs, parsed) + + res.TypedSpec().ListenAddresses = append(res.TypedSpec().ListenAddresses, netip.AddrPortFrom(parsed, 53)) + res.TypedSpec().ServiceHostDNSAddress = parsed + } + + if slices.ContainsFunc( + cfgProvider.Cluster().Network().PodCIDRs(), + func(cidr string) bool { return netip.MustParsePrefix(cidr).Addr().Is6() }, + ) { + parsed := netip.MustParseAddr(constants.HostDNSAddressV6) + newServiceAddrs = append(newServiceAddrs, parsed) - res.TypedSpec().ListenAddresses = append(res.TypedSpec().ListenAddresses, netip.AddrPortFrom(newServiceAddr, 53)) - res.TypedSpec().ServiceHostDNSAddress = newServiceAddr + res.TypedSpec().ListenAddresses = append(res.TypedSpec().ListenAddresses, netip.AddrPortFrom(parsed, 53)) + res.TypedSpec().ServiceHostDNSAddressV6 = parsed } return nil @@ -113,65 +134,25 @@ func (ctrl *HostDNSConfigController) Run(ctx context.Context, r controller.Runti return fmt.Errorf("error writing host dns config: %w", err) } - var touched *network.AddressSpec - - if !value.IsZero(newServiceAddr) { - touched, err = updateSpec(ctx, r, newServiceAddr, logger) + for _, newServiceAddr := range newServiceAddrs { + err := updateSpec(ctx, r, newServiceAddr, logger) if err != nil { return err } } - if err = ctrl.cleanupAddressSpecs( - ctx, - r, - func(id resource.ID) bool { - if touched == nil { - return false - } - - return id == touched.Metadata().ID() - }, - logger, - ); err != nil { - return err - } - - r.ResetRestartBackoff() - } -} - -func (ctrl *HostDNSConfigController) cleanupAddressSpecs(ctx context.Context, r controller.Runtime, checkResource func(id resource.ID) bool, logger *zap.Logger) error { - list, err := safe.ReaderList[*network.AddressSpec](ctx, r, network.NewAddressSpec(network.ConfigNamespaceName, "").Metadata()) - if err != nil { - return err - } - - for address := range list.All() { - if address.Metadata().Owner() != ctrl.Name() { - continue - } - - if checkResource(address.Metadata().ID()) { - continue - } - - if err = r.Destroy(ctx, address.Metadata()); err != nil && !state.IsNotFoundError(err) { + if err = safe.CleanupOutputs[*network.HostDNSConfig](ctx, r); err != nil { return err } - - logger.Info("destroyed address spec", zap.String("address_id", address.Metadata().ID())) } - - return nil } -func updateSpec(ctx context.Context, r controller.Runtime, newServiceAddr netip.Addr, logger *zap.Logger) (*network.AddressSpec, error) { +func updateSpec(ctx context.Context, r controller.Runtime, newServiceAddr netip.Addr, logger *zap.Logger) error { newDNSAddrPrefix := netip.PrefixFrom(newServiceAddr, newServiceAddr.BitLen()) logger.Debug("creating new host dns address spec", zap.String("address", newServiceAddr.String())) - res, err := safe.WriterModifyWithResult( + err := safe.WriterModify( ctx, r, network.NewAddressSpec( @@ -192,14 +173,19 @@ func updateSpec(ctx context.Context, r controller.Runtime, newServiceAddr netip. spec.Flags = nethelpers.AddressFlags(nethelpers.AddressPermanent) spec.LinkName = "lo" - spec.Scope = nethelpers.ScopeHost + + if newServiceAddr.Is6() && newServiceAddr.IsPrivate() { + spec.Scope = nethelpers.ScopeGlobal + } else { + spec.Scope = nethelpers.ScopeHost + } return nil }, ) if err != nil { - return nil, fmt.Errorf("error modifying address: %w", err) + return fmt.Errorf("error modifying address: %w", err) } - return res, nil + return nil } diff --git a/internal/app/machined/pkg/controllers/network/nftables_chain_config.go b/internal/app/machined/pkg/controllers/network/nftables_chain_config.go index cc10e909945..184bcbd1e69 100644 --- a/internal/app/machined/pkg/controllers/network/nftables_chain_config.go +++ b/internal/app/machined/pkg/controllers/network/nftables_chain_config.go @@ -19,6 +19,7 @@ import ( "github.com/siderolabs/go-pointer" "go.uber.org/zap" + cfg "github.com/siderolabs/talos/pkg/machinery/config/config" "github.com/siderolabs/talos/pkg/machinery/constants" "github.com/siderolabs/talos/pkg/machinery/nethelpers" "github.com/siderolabs/talos/pkg/machinery/resources/config" @@ -154,8 +155,6 @@ func (ctrl *NfTablesChainConfigController) Run(ctx context.Context, r controller if cfg.Config().Machine() != nil && cfg.Config().Cluster() != nil { if cfg.Config().Machine().Features().HostDNS().ForwardKubeDNSToHost() { - hostDNSIP := netip.MustParseAddr(constants.HostDNSAddress) - // allow traffic to host DNS for _, protocol := range []nethelpers.Protocol{nethelpers.ProtocolUDP, nethelpers.ProtocolTCP} { spec.Rules = append(spec.Rules, @@ -170,7 +169,7 @@ func (ctrl *NfTablesChainConfigController) Run(ctx context.Context, r controller ), }, MatchDestinationAddress: &network.NfTablesAddressMatch{ - IncludeSubnets: []netip.Prefix{netip.PrefixFrom(hostDNSIP, hostDNSIP.BitLen())}, + IncludeSubnets: hostDNSSubnets(cfg.Config().Cluster().Network()), }, MatchLayer4: &network.NfTablesLayer4Match{ Protocol: protocol, @@ -256,3 +255,20 @@ func (ctrl *NfTablesChainConfigController) Run(ctx context.Context, r controller } } } + +func hostDNSSubnets(clusterNetwork cfg.ClusterNetwork) []netip.Prefix { + result := []netip.Addr{hostDNSIPv4} + + for _, podCIDR := range clusterNetwork.PodCIDRs() { + if netip.MustParsePrefix(podCIDR).Addr().Is6() { + result = append(result, hostDNSIPv6) + } + } + + return xslices.Map(result, func(a netip.Addr) netip.Prefix { return netip.PrefixFrom(a, a.BitLen()) }) +} + +var ( + hostDNSIPv4 = netip.MustParseAddr(constants.HostDNSAddress) + hostDNSIPv6 = netip.MustParseAddr(constants.HostDNSAddressV6) +) diff --git a/internal/app/machined/pkg/xcontext/xcontext.go b/internal/app/machined/pkg/xcontext/xcontext.go new file mode 100644 index 00000000000..32dca45de85 --- /dev/null +++ b/internal/app/machined/pkg/xcontext/xcontext.go @@ -0,0 +1,28 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Package xcontext provides a small utils for context package +package xcontext + +import "context" + +// AfterFuncSync is like [context.AfterFunc] but it blocks until the function is executed. +func AfterFuncSync(ctx context.Context, fn func()) func() bool { + stopChan := make(chan struct{}) + + stop := context.AfterFunc(ctx, func() { + defer close(stopChan) + + fn() + }) + + return func() bool { + result := stop() + if !result { + <-stopChan + } + + return result + } +} diff --git a/internal/pkg/dns/dns.go b/internal/pkg/dns/dns.go index 6a8be932fcc..5eaa7619f4d 100644 --- a/internal/pkg/dns/dns.go +++ b/internal/pkg/dns/dns.go @@ -9,12 +9,10 @@ import ( "context" "errors" "fmt" - "io" "iter" "net" "net/netip" "slices" - "strings" "sync" "sync/atomic" "syscall" @@ -207,7 +205,7 @@ func NewNodeHandler(next plugin.Handler, hostMapper HostMapper, logger *zap.Logg // HostMapper is a name to node mapper. type HostMapper interface { - ResolveAddr(ctx context.Context, qType uint16, name string) []netip.Addr + ResolveAddr(ctx context.Context, qType uint16, name string) (iter.Seq[netip.Addr], bool) } // NodeHandler try to resolve dns request to a node. If required node is not found, it will move to the next handler. @@ -238,14 +236,19 @@ func (h *NodeHandler) ServeDNS(ctx context.Context, wrt dns.ResponseWriter, msg req := request.Request{W: wrt, Req: msg} // Check if the request is for a node. - result := h.mapper.ResolveAddr(ctx, req.QType(), req.Name()) - if len(result) == 0 { + result, ok := h.mapper.ResolveAddr(ctx, req.QType(), req.Name()) + if !ok { + return h.next.ServeDNS(ctx, wrt, msg) + } + + answers := mapAnswers(result, req.Name()) + if len(answers) == 0 { return h.next.ServeDNS(ctx, wrt, msg) } resp := new(dns.Msg).SetReply(req.Req) resp.Authoritative = true - resp.Answer = mapAnswers(result, req.Name()) + resp.Answer = answers err := wrt.WriteMsg(resp) if err != nil { @@ -256,10 +259,10 @@ func (h *NodeHandler) ServeDNS(ctx context.Context, wrt dns.ResponseWriter, msg return dns.RcodeSuccess, nil } -func mapAnswers(addrs []netip.Addr, name string) []dns.RR { +func mapAnswers(addrs iter.Seq[netip.Addr], name string) []dns.RR { var result []dns.RR - for _, addr := range addrs { + for addr := range addrs { switch { case addr.Is4(): result = append(result, &dns.A{ @@ -295,89 +298,6 @@ func (h *NodeHandler) SetEnabled(enabled bool) { h.enabled.Store(enabled) } -// ServerOptions is a Server options. -type ServerOptions struct { - Listener net.Listener - PacketConn net.PacketConn - Handler dns.Handler - ReadTimeout time.Duration - WriteTimeout time.Duration - IdleTimeout func() time.Duration - MaxTCPQueries int - Logger *zap.Logger -} - -// NewServer creates a new Server. -func NewServer(opts ServerOptions) *Server { - return &Server{ - srv: &dns.Server{ - Listener: opts.Listener, - PacketConn: opts.PacketConn, - Handler: opts.Handler, - UDPSize: dns.DefaultMsgSize, // 4096 since default is [dns.MinMsgSize] = 512 bytes, which is too small. - ReadTimeout: opts.ReadTimeout, - WriteTimeout: opts.WriteTimeout, - IdleTimeout: opts.IdleTimeout, - MaxTCPQueries: opts.MaxTCPQueries, - }, - logger: opts.Logger, - } -} - -// Server is a dns server. -type Server struct { - srv *dns.Server - logger *zap.Logger -} - -// Start starts the dns server. Returns a function to stop the server. -func (s *Server) Start(onDone func(err error)) (stop func(), stopped <-chan struct{}) { - done := make(chan struct{}) - - fn := sync.OnceFunc(func() { - for { - err := s.srv.Shutdown() - if err != nil { - if strings.Contains(err.Error(), "server not started") { - // There a possible scenario where `go func()` not yet reached `ActivateAndServe` and yielded CPU - // time to another goroutine and then this closure reached `Shutdown`. In that case - // `ActivateAndServe` will actually start after `Shutdown` and this closure will block forever - // because `go func()` will never exit and close `done` channel. - continue - } - - s.logger.Error("error shutting down dns server", zap.Error(err)) - } - - break - } - - closer := io.Closer(s.srv.Listener) - if closer == nil { - closer = s.srv.PacketConn - } - - if closer != nil { - err := closer.Close() - if err != nil && !errors.Is(err, net.ErrClosed) { - s.logger.Error("error closing dns server listener", zap.Error(err)) - } else { - s.logger.Debug("dns server listener closed") - } - } - - <-done - }) - - go func() { - defer close(done) - - onDone(s.srv.ActivateAndServe()) - }() - - return fn, done -} - // NewTCPListener creates a new TCP listener. func NewTCPListener(network, addr string, control ControlFn) (net.Listener, error) { network, ok := networkNames[network] diff --git a/internal/pkg/dns/dns_test.go b/internal/pkg/dns/dns_test.go index e15ac7992e2..66d94fd801d 100644 --- a/internal/pkg/dns/dns_test.go +++ b/internal/pkg/dns/dns_test.go @@ -6,22 +6,26 @@ package dns_test import ( "context" + "iter" "net" "net/netip" + "runtime" "slices" + "strings" "testing" "time" "github.com/coredns/coredns/plugin/pkg/proxy" dnssrv "github.com/miekg/dns" - "github.com/siderolabs/gen/ensure" - "github.com/siderolabs/gen/xiter" + "github.com/siderolabs/gen/maps" "github.com/siderolabs/gen/xslices" "github.com/siderolabs/gen/xtesting/check" "github.com/stretchr/testify/require" + "github.com/thejerf/suture/v4" "go.uber.org/zap/zaptest" "github.com/siderolabs/talos/internal/pkg/dns" + "github.com/siderolabs/talos/pkg/machinery/resources/cluster" ) func TestDNS(t *testing.T) { @@ -76,47 +80,98 @@ func TestDNS(t *testing.T) { }, } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - stop := newServer(t, test.nameservers...) - t.Cleanup(stop) + for _, dnsAddr := range []string{"127.0.0.1:10700", "[::1]:10700"} { + for _, test := range tests { + t.Run(dnsAddr+"/"+test.name, func(t *testing.T) { + stop := newManager(t, test.nameservers...) + t.Cleanup(stop) - time.Sleep(10 * time.Millisecond) + time.Sleep(10 * time.Millisecond) - r, err := dnssrv.Exchange(createQuery(test.hostname), "127.0.0.53:10700") - test.errCheck(t, err) + r, err := dnssrv.Exchange(createQuery(test.hostname), dnsAddr) + test.errCheck(t, err) - if r != nil { - require.Equal(t, test.expectedCode, r.Rcode, r) - } + if r != nil { + require.Equal(t, test.expectedCode, r.Rcode, r) + } - t.Logf("r: %s", r) - }) + t.Logf("r: %s", r) + }) + } } } func TestDNSEmptyDestinations(t *testing.T) { - stop := newServer(t) + stop := newManager(t) defer stop() time.Sleep(10 * time.Millisecond) - r, err := dnssrv.Exchange(createQuery("google.com"), "127.0.0.53:10700") + r, err := dnssrv.Exchange(createQuery("google.com"), "127.0.0.1:10700") + require.NoError(t, err) + require.Equal(t, dnssrv.RcodeServerFailure, r.Rcode, r) + + r, err = dnssrv.Exchange(createQuery("google.com"), "127.0.0.1:10700") + require.NoError(t, err) + require.Equal(t, dnssrv.RcodeServerFailure, r.Rcode, r) + + r, err = dnssrv.Exchange(createQuery("google.com"), "[::1]:10700") require.NoError(t, err) require.Equal(t, dnssrv.RcodeServerFailure, r.Rcode, r) - r, err = dnssrv.Exchange(createQuery("google.com"), "127.0.0.53:10700") + r, err = dnssrv.Exchange(createQuery("google.com"), "[::1]:10700") require.NoError(t, err) require.Equal(t, dnssrv.RcodeServerFailure, r.Rcode, r) stop() } -func newServer(t *testing.T, nameservers ...string) func() { - l := zaptest.NewLogger(t) +func TestGC_NOGC(t *testing.T) { + tests := map[string]bool{ + "ClearAll": false, + "No ClearAll": true, + } + + for name, f := range tests { + t.Run(name, func(t *testing.T) { + m := dns.NewManager(&testReader{}, func(e suture.Event) { t.Log("dns-runners event:", e) }, zaptest.NewLogger(t)) + + m.ServeBackground(context.Background()) + m.ServeBackground(context.Background()) + require.Panics(t, func() { m.ServeBackground(context.TODO()) }) + + for _, err := range m.RunAll(slices.Values([]dns.AddressPair{ + {Network: "udp", Addr: netip.MustParseAddrPort("127.0.0.1:10700")}, + {Network: "udp", Addr: netip.MustParseAddrPort("127.0.0.1:10701")}, + {Network: "udp", Addr: netip.MustParseAddrPort("[::1]:10700")}, + {Network: "udp", Addr: netip.MustParseAddrPort("[::1]:10701")}, + }), false) { + require.NoError(t, err) + } + + require.NoError(t, m.ClearAll(f)) + + m = nil + + for range 100 { + runtime.GC() + } + }) + } +} + +func newManager(t *testing.T, nameservers ...string) func() { + m := dns.NewManager(&testReader{}, func(e suture.Event) { + t.Log("dns-runners event:", e) + }, zaptest.NewLogger(t)) + + m.AllowNodeResolving(true) - handler := dns.NewHandler(l) - t.Cleanup(handler.Stop) + t.Cleanup(func() { + if err := m.ClearAll(false); err != nil { + t.Logf("error stopping dns runners: %v", err) + } + }) pxs := xslices.Map(nameservers, func(ns string) *proxy.Proxy { p := proxy.NewProxy(ns, net.JoinHostPort(ns, "53"), "dns") @@ -127,30 +182,44 @@ func newServer(t *testing.T, nameservers ...string) func() { return p }) - handler.SetProxy(xiter.Values(slices.All(pxs))) + ctx, cancel := context.WithCancel(context.Background()) + t.Cleanup(cancel) - pc, err := dns.NewUDPPacketConn("udp", "127.0.0.53:10700", ensure.Value(dns.MakeControl("udp", false))) - require.NoError(t, err) + m.SetUpstreams(slices.Values(pxs)) - nodeHandler := dns.NewNodeHandler(handler, &testResolver{}, l) + m.ServeBackground(ctx) + m.ServeBackground(ctx) - nodeHandler.SetEnabled(true) + for _, err := range m.RunAll(slices.Values([]dns.AddressPair{ + {Network: "udp", Addr: netip.MustParseAddrPort("127.0.0.1:10700")}, + {Network: "udp", Addr: netip.MustParseAddrPort("127.0.0.1:10701")}, + {Network: "tcp", Addr: netip.MustParseAddrPort("127.0.0.1:10700")}, + }), false) { + if err != nil && strings.Contains(err.Error(), "failed to set TCP_FASTOPEN") { + continue + } - srv := dns.NewServer(dns.ServerOptions{ - PacketConn: pc, - Handler: dns.NewCache(nodeHandler, l), - Logger: l, - }) + require.NoError(t, err) + } - stop, _ := srv.Start(func(err error) { - if err != nil { - t.Errorf("error running dns server: %v", err) + for _, err := range m.RunAll(slices.Values([]dns.AddressPair{ + {Network: "udp", Addr: netip.MustParseAddrPort("127.0.0.1:10700")}, + {Network: "tcp", Addr: netip.MustParseAddrPort("127.0.0.1:10700")}, + {Network: "udp", Addr: netip.MustParseAddrPort("[::1]:10700")}, + {Network: "tcp", Addr: netip.MustParseAddrPort("[::1]:10700")}, + }), false) { + if err != nil && strings.Contains(err.Error(), "failed to set TCP_FASTOPEN") { + continue } - t.Logf("dns server stopped") - }) + require.NoError(t, err) + } - return stop + return func() { + if err := m.ClearAll(false); err != nil { + t.Logf("error stopping dns runners: %v", err) + } + } } func createQuery(name string) *dnssrv.Msg { @@ -169,19 +238,21 @@ func createQuery(name string) *dnssrv.Msg { } } -type testResolver struct{} +type testReader struct{} -func (*testResolver) ResolveAddr(_ context.Context, qType uint16, name string) []netip.Addr { - if qType != dnssrv.TypeA { - return nil +func (r *testReader) ReadMembers(context.Context) (iter.Seq[*cluster.Member], error) { + namesToAddresses := map[string][]netip.Addr{ + "talos-default-controlplane-1": {netip.MustParseAddr("172.20.0.2")}, + "talos-default-worker-1": {netip.MustParseAddr("172.20.0.3")}, } - switch name { - case "talos-default-controlplane-1.": - return []netip.Addr{netip.MustParseAddr("172.20.0.2")} - case "talos-default-worker-1.": - return []netip.Addr{netip.MustParseAddr("172.20.0.3")} - default: - return nil - } + result := maps.ToSlice(namesToAddresses, func(k string, v []netip.Addr) *cluster.Member { + result := cluster.NewMember(cluster.NamespaceName, k) + + result.TypedSpec().Addresses = v + + return result + }) + + return slices.Values(result), nil } diff --git a/internal/pkg/dns/manager.go b/internal/pkg/dns/manager.go new file mode 100644 index 00000000000..bd8510ccc01 --- /dev/null +++ b/internal/pkg/dns/manager.go @@ -0,0 +1,318 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package dns + +import ( + "context" + "errors" + "fmt" + "iter" + "net/netip" + "runtime" + "slices" + "strings" + "time" + + "github.com/coredns/coredns/plugin/pkg/proxy" + "github.com/hashicorp/go-multierror" + dnssrv "github.com/miekg/dns" + "github.com/siderolabs/gen/xiter" + "github.com/thejerf/suture/v4" + "go.uber.org/zap" + + "github.com/siderolabs/talos/pkg/machinery/resources/cluster" +) + +// ErrCreatingRunner is an error that occurs when creating a runner. +var ErrCreatingRunner = errors.New("error creating runner") + +// Manager manages DNS runners. +type Manager struct { + originalCtx context.Context //nolint:containedctx + handler *Handler + nodeHandler *NodeHandler + rootHandler *Cache + s *suture.Supervisor + supervisorCh <-chan error + logger *zap.Logger + runners map[AddressPair]suture.ServiceToken +} + +// NewManager creates a new manager. +func NewManager(mr MemberReader, hook suture.EventHook, logger *zap.Logger) *Manager { + handler := NewHandler(logger) + nodeHandler := NewNodeHandler(handler, &addrResolver{mr: mr}, logger) + rootHandler := NewCache(nodeHandler, logger) + + m := &Manager{ + handler: handler, + nodeHandler: nodeHandler, + rootHandler: rootHandler, + s: suture.New("dns-resolve-cache-runners", suture.Spec{EventHook: hook}), + logger: logger, + runners: map[AddressPair]suture.ServiceToken{}, + } + + // If we lost ref to the manager. Ensure finalizer is called and all upstreams are collected. + runtime.SetFinalizer(m, (*Manager).finalize) + + return m +} + +// ServeBackground starts the manager in the background. It panics if the manager is not initialized or if it's called +// more than once. +func (m *Manager) ServeBackground(ctx context.Context) { + switch { + case m.originalCtx == nil: + m.originalCtx = ctx + case m.originalCtx != ctx: + panic("Manager.ServeBackground is called with a different context") + case m.originalCtx == ctx: + return + } + + m.supervisorCh = m.s.ServeBackground(ctx) +} + +// AddressPair represents a network and address with port. +type AddressPair struct { + Network string + Addr netip.AddrPort +} + +// String returns a string representation of the address pair. +func (a AddressPair) String() string { return "Network: " + a.Network + ", Addr: " + a.Addr.String() } + +// RunAll updates and run the runners managed by the manager. It returns an iterator which yields the address pairs for +// all running and attempted ro run configurations. It's mandatory to range over the iterator to ensure all runners are updated. +func (m *Manager) RunAll(pairs iter.Seq[AddressPair], forwardEnabled bool) iter.Seq2[RunResult, error] { + return func(yield func(RunResult, error) bool) { + preserve := make(map[AddressPair]struct{}, len(m.runners)) + + for cfg := range pairs { + preserve[cfg] = struct{}{} + + if _, ok := m.runners[cfg]; ok { + if !yield(makeResult(cfg, StatusRunning), nil) { + return + } + + continue + } + + opts, err := newDNSRunnerOpts(cfg, m.rootHandler, forwardEnabled) + if err != nil { + err = fmt.Errorf("%w: %w", ErrCreatingRunner, err) + } else { + m.runners[cfg] = m.s.Add(NewRunner(opts, m.logger)) + } + + if !yield(makeResult(cfg, StatusNew), err) { + return + } + } + + for cfg, token := range m.runners { + if _, ok := preserve[cfg]; ok { + continue + } + + err := m.s.RemoveAndWait(token, 0) + if err != nil { + err = fmt.Errorf("error removing runner: %w", err) + } + + if !yield(makeResult(cfg, StatusRemoved), err) { + return + } + + delete(m.runners, cfg) + } + } +} + +func makeResult(cfg AddressPair, s Status) RunResult { return RunResult{AddressPair: cfg, Status: s} } + +// AllowNodeResolving enables or disables the node resolving feature. +func (m *Manager) AllowNodeResolving(enabled bool) { m.nodeHandler.SetEnabled(enabled) } + +// SetUpstreams sets the upstreams for the DNS handler. It returns true if the upstreams were updated, false otherwise. +func (m *Manager) SetUpstreams(prxs iter.Seq[*proxy.Proxy]) bool { return m.handler.SetProxy(prxs) } + +// ClearAll stops and removes all runners. It returns an iterator which yields the address pairs that were removed +// and/or errors that occurred during the removal process. It's mandatory to range over the iterator to ensure all +// runners are stopped. +func (m *Manager) ClearAll(dry bool) error { + if dry { + return nil + } + + var multiErr *multierror.Error + + for _, err := range m.clearAll() { + if err != nil { + multiErr = multierror.Append(multiErr, err) + } + } + + return multiErr.ErrorOrNil() +} + +func (m *Manager) clearAll() iter.Seq2[AddressPair, error] { + return func(yield func(AddressPair, error) bool) { + if len(m.runners) == 0 { + return + } + + defer m.handler.Stop() + + removeAndWait := m.s.RemoveAndWait + if m.originalCtx.Err() != nil { + // ctx canceled, no reason to remove runners from Supervisor since they are already dropped + removeAndWait = func(id suture.ServiceToken, timeout time.Duration) error { return nil } + } + + for runData, token := range m.runners { + err := removeAndWait(token, 0) + if err != nil { + err = fmt.Errorf("error removing runner: %w", err) + } + + if !yield(runData, err) { + return + } + + delete(m.runners, runData) + } + } +} + +func (m *Manager) finalize() { + for data, err := range m.clearAll() { + if err != nil { + m.logger.Error("error stopping dns runner", zap.Error(err)) + } + + m.logger.Info( + "dns runner stopped from finalizer!", + zap.String("address", data.Addr.String()), + zap.String("network", data.Network), + ) + } +} + +// Done reports if superwisor finished execution. +func (m *Manager) Done() <-chan error { + return m.supervisorCh +} + +type addrResolver struct { + mr MemberReader +} + +func (s *addrResolver) ResolveAddr(ctx context.Context, qType uint16, name string) (iter.Seq[netip.Addr], bool) { + name = strings.TrimRight(name, ".") + + items, err := s.mr.ReadMembers(ctx) + if err != nil { + return nil, false + } + + found, ok := xiter.Find(func(res *cluster.Member) bool { + return fqdnMatch(name, res.TypedSpec().Hostname) || fqdnMatch(name, res.Metadata().ID()) + }, items) + if !ok { + return nil, false + } + + return xiter.Filter( + func(addr netip.Addr) bool { + return (qType == dnssrv.TypeA && addr.Is4()) || (qType == dnssrv.TypeAAAA && addr.Is6()) + }, + slices.Values(found.TypedSpec().Addresses), + ), true +} + +func fqdnMatch(what, where string) bool { + what = strings.TrimRight(what, ".") + where = strings.TrimRight(where, ".") + + if what == where { + return true + } + + first, _, found := strings.Cut(where, ".") + if !found { + return false + } + + return what == first +} + +// MemberReader is an interface to read members. +type MemberReader interface { + ReadMembers(ctx context.Context) (iter.Seq[*cluster.Member], error) +} + +func newDNSRunnerOpts(cfg AddressPair, rootHandler dnssrv.Handler, forwardEnabled bool) (RunnerOptions, error) { + if cfg.Addr.Addr().Is6() && !strings.HasSuffix(cfg.Network, "6") { + cfg.Network += "6" + } + + var serverOpts RunnerOptions + + controlFn, ctrlErr := MakeControl(cfg.Network, forwardEnabled) + if ctrlErr != nil { + return serverOpts, fmt.Errorf("error creating %q control function: %w", cfg.Network, ctrlErr) + } + + switch cfg.Network { + case "udp", "udp6": + packetConn, err := NewUDPPacketConn(cfg.Network, cfg.Addr.String(), controlFn) + if err != nil { + return serverOpts, fmt.Errorf("error creating %q packet conn: %w", cfg.Network, err) + } + + serverOpts = RunnerOptions{ + PacketConn: packetConn, + Handler: rootHandler, + } + + case "tcp", "tcp6": + listener, err := NewTCPListener(cfg.Network, cfg.Addr.String(), controlFn) + if err != nil { + return serverOpts, fmt.Errorf("error creating %q listener: %w", cfg.Network, err) + } + + serverOpts = RunnerOptions{ + Listener: listener, + Handler: rootHandler, + ReadTimeout: 3 * time.Second, + WriteTimeout: 5 * time.Second, + IdleTimeout: func() time.Duration { return 10 * time.Second }, + MaxTCPQueries: -1, + } + } + + return serverOpts, nil +} + +// RunResult represents the result of a RunAll iteration. +type RunResult struct { + AddressPair + Status Status +} + +// Status represents the status of a runner. +type Status int + +const ( + // StatusNew represents a new runner. + StatusNew Status = iota + // StatusRunning represents a already running runner. + StatusRunning + // StatusRemoved represents a removed runner. + StatusRemoved +) diff --git a/internal/pkg/dns/runnner.go b/internal/pkg/dns/runnner.go new file mode 100644 index 00000000000..f0725de97d7 --- /dev/null +++ b/internal/pkg/dns/runnner.go @@ -0,0 +1,108 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package dns + +import ( + "context" + "errors" + "io" + "net" + "strings" + "time" + + "github.com/miekg/dns" + "go.uber.org/zap" + + "github.com/siderolabs/talos/internal/app/machined/pkg/xcontext" +) + +// RunnerOptions is a [Runner] options. +type RunnerOptions struct { + Listener net.Listener + PacketConn net.PacketConn + Handler dns.Handler + ReadTimeout time.Duration + WriteTimeout time.Duration + IdleTimeout func() time.Duration + MaxTCPQueries int +} + +// NewRunner creates a new [Runner]. +func NewRunner(opts RunnerOptions, l *zap.Logger) *Runner { + return &Runner{ + srv: &dns.Server{ + Listener: opts.Listener, + PacketConn: opts.PacketConn, + Handler: opts.Handler, + UDPSize: dns.DefaultMsgSize, // 4096 since default is [dns.MinMsgSize] = 512 bytes, which is too small. + ReadTimeout: opts.ReadTimeout, + WriteTimeout: opts.WriteTimeout, + IdleTimeout: opts.IdleTimeout, + MaxTCPQueries: opts.MaxTCPQueries, + }, + logger: l, + } +} + +// Runner is a DNS server runner. +type Runner struct { + srv *dns.Server + logger *zap.Logger +} + +// Serve starts the DNS server. +func (r *Runner) Serve(ctx context.Context) error { + detach := xcontext.AfterFuncSync(ctx, r.close) + defer func() { + if !detach() { + return + } + + r.close() + }() + + return r.srv.ActivateAndServe() +} + +func (r *Runner) close() { + l := r.logger + + if r.srv.Listener != nil { + l = l.With(zap.String("net", "tcp"), zap.String("local_addr", r.srv.Listener.Addr().String())) + } else if r.srv.PacketConn != nil { + l = l.With(zap.String("net", "udp"), zap.String("local_addr", r.srv.PacketConn.LocalAddr().String())) + } + + for { + err := r.srv.Shutdown() + if err != nil { + if strings.Contains(err.Error(), "server not started") { + // There a possible scenario where `go func()` not yet reached `ActivateAndServe` and yielded CPU + // time to another goroutine and then this closure reached `Shutdown`. In that case + // `dns.Server.ActivateAndServe` will actually start after `Shutdown` and this closure will block forever + // because `go func()` will never exit and close `done` channel. + continue + } + + l.Error("error shutting down dns server", zap.Error(err)) + } + + closer := io.Closer(r.srv.Listener) + if closer == nil { + closer = r.srv.PacketConn + } + + if closer != nil { + err = closer.Close() + if err != nil && !errors.Is(err, net.ErrClosed) { + l.Error("error closing dns server listener", zap.Error(err)) + } else { + l.Debug("dns server listener closed") + } + } + + break + } +} diff --git a/pkg/machinery/api/resource/definitions/network/network.pb.go b/pkg/machinery/api/resource/definitions/network/network.pb.go index 8fbe9fbe768..e2b996567d7 100644 --- a/pkg/machinery/api/resource/definitions/network/network.pb.go +++ b/pkg/machinery/api/resource/definitions/network/network.pb.go @@ -889,10 +889,11 @@ type HostDNSConfigSpec struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` - ListenAddresses []*common.NetIPPort `protobuf:"bytes,2,rep,name=listen_addresses,json=listenAddresses,proto3" json:"listen_addresses,omitempty"` - ServiceHostDnsAddress *common.NetIP `protobuf:"bytes,3,opt,name=service_host_dns_address,json=serviceHostDnsAddress,proto3" json:"service_host_dns_address,omitempty"` - ResolveMemberNames bool `protobuf:"varint,4,opt,name=resolve_member_names,json=resolveMemberNames,proto3" json:"resolve_member_names,omitempty"` + Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` + ListenAddresses []*common.NetIPPort `protobuf:"bytes,2,rep,name=listen_addresses,json=listenAddresses,proto3" json:"listen_addresses,omitempty"` + ServiceHostDnsAddress *common.NetIP `protobuf:"bytes,3,opt,name=service_host_dns_address,json=serviceHostDnsAddress,proto3" json:"service_host_dns_address,omitempty"` + ResolveMemberNames bool `protobuf:"varint,4,opt,name=resolve_member_names,json=resolveMemberNames,proto3" json:"resolve_member_names,omitempty"` + ServiceHostDnsAddressV6 *common.NetIP `protobuf:"bytes,5,opt,name=service_host_dns_address_v6,json=serviceHostDnsAddressV6,proto3" json:"service_host_dns_address_v6,omitempty"` } func (x *HostDNSConfigSpec) Reset() { @@ -953,6 +954,13 @@ func (x *HostDNSConfigSpec) GetResolveMemberNames() bool { return false } +func (x *HostDNSConfigSpec) GetServiceHostDnsAddressV6() *common.NetIP { + if x != nil { + return x.ServiceHostDnsAddressV6 + } + return nil +} + // HostnameSpecSpec describes node hostname. type HostnameSpecSpec struct { state protoimpl.MessageState @@ -3815,7 +3823,7 @@ var file_resource_definitions_network_network_proto_rawDesc = []byte{ 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x68, 0x61, - 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x41, 0x64, 0x64, 0x72, 0x22, 0xe5, 0x01, 0x0a, 0x11, 0x48, + 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x41, 0x64, 0x64, 0x72, 0x22, 0xb2, 0x02, 0x0a, 0x11, 0x48, 0x6f, 0x73, 0x74, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x3c, 0x0a, 0x10, 0x6c, 0x69, @@ -3830,398 +3838,449 @@ var file_resource_definitions_network_network_proto_rawDesc = []byte{ 0x12, 0x30, 0x0a, 0x14, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x10, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x53, - 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, + 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x1b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x68, 0x6f, + 0x73, 0x74, 0x5f, 0x64, 0x6e, 0x73, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x76, + 0x36, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x17, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x48, + 0x6f, 0x73, 0x74, 0x44, 0x6e, 0x73, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x56, 0x36, 0x22, + 0xa7, 0x01, 0x0a, 0x10, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x70, 0x65, 0x63, + 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x0b, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x22, 0x50, 0x0a, 0x12, 0x48, 0x6f, 0x73, + 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, + 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x31, 0x0a, 0x0f, 0x4c, + 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1e, + 0x0a, 0x0a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x9b, + 0x06, 0x0a, 0x0c, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x12, 0x0e, 0x0a, + 0x02, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x75, 0x70, 0x12, 0x10, 0x0a, + 0x03, 0x6d, 0x74, 0x75, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6d, 0x74, 0x75, 0x12, + 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, + 0x69, 0x6e, 0x64, 0x12, 0x48, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, + 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x4c, + 0x69, 0x6e, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, + 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4c, + 0x0a, 0x0a, 0x62, 0x6f, 0x6e, 0x64, 0x5f, 0x73, 0x6c, 0x61, 0x76, 0x65, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, + 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x42, 0x6f, 0x6e, 0x64, 0x53, 0x6c, 0x61, 0x76, + 0x65, 0x52, 0x09, 0x62, 0x6f, 0x6e, 0x64, 0x53, 0x6c, 0x61, 0x76, 0x65, 0x12, 0x52, 0x0a, 0x0c, + 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x5f, 0x73, 0x6c, 0x61, 0x76, 0x65, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, + 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x53, 0x6c, + 0x61, 0x76, 0x65, 0x52, 0x0b, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x53, 0x6c, 0x61, 0x76, 0x65, + 0x12, 0x40, 0x0a, 0x04, 0x76, 0x6c, 0x61, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, + 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x2e, 0x56, 0x4c, 0x41, 0x4e, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x76, 0x6c, + 0x61, 0x6e, 0x12, 0x53, 0x0a, 0x0b, 0x62, 0x6f, 0x6e, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x74, 0x65, + 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x42, 0x6f, 0x6e, + 0x64, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0a, 0x62, 0x6f, 0x6e, + 0x64, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x12, 0x59, 0x0a, 0x0d, 0x62, 0x72, 0x69, 0x64, 0x67, + 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, + 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x2e, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, + 0x53, 0x70, 0x65, 0x63, 0x52, 0x0c, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x4d, 0x61, 0x73, 0x74, + 0x65, 0x72, 0x12, 0x4f, 0x0a, 0x09, 0x77, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x18, + 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x57, 0x69, 0x72, 0x65, 0x67, + 0x75, 0x61, 0x72, 0x64, 0x53, 0x70, 0x65, 0x63, 0x52, 0x09, 0x77, 0x69, 0x72, 0x65, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, + 0x79, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, - 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x22, 0x50, 0x0a, 0x12, - 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, - 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, - 0x0a, 0x0a, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x31, - 0x0a, 0x0f, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x70, 0x65, - 0x63, 0x12, 0x1e, 0x0a, 0x0a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x22, 0x9b, 0x06, 0x0a, 0x0c, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, - 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, - 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, - 0x12, 0x0e, 0x0a, 0x02, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x75, 0x70, - 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x74, 0x75, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6d, - 0x74, 0x75, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x48, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, - 0x72, 0x73, 0x4c, 0x69, 0x6e, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x4c, 0x0a, 0x0a, 0x62, 0x6f, 0x6e, 0x64, 0x5f, 0x73, 0x6c, 0x61, 0x76, 0x65, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x42, 0x6f, 0x6e, 0x64, 0x53, - 0x6c, 0x61, 0x76, 0x65, 0x52, 0x09, 0x62, 0x6f, 0x6e, 0x64, 0x53, 0x6c, 0x61, 0x76, 0x65, 0x12, - 0x52, 0x0a, 0x0c, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x5f, 0x73, 0x6c, 0x61, 0x76, 0x65, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x42, 0x72, 0x69, 0x64, 0x67, - 0x65, 0x53, 0x6c, 0x61, 0x76, 0x65, 0x52, 0x0b, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x53, 0x6c, - 0x61, 0x76, 0x65, 0x12, 0x40, 0x0a, 0x04, 0x76, 0x6c, 0x61, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x22, 0xae, 0x0a, 0x0a, + 0x0e, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, + 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x48, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, + 0x73, 0x4c, 0x69, 0x6e, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x1d, 0x0a, 0x0a, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, + 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x66, + 0x6c, 0x61, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x68, 0x61, 0x72, + 0x64, 0x77, 0x61, 0x72, 0x65, 0x41, 0x64, 0x64, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x72, 0x6f, + 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0d, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, + 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x74, 0x75, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6d, + 0x74, 0x75, 0x12, 0x1d, 0x0a, 0x0a, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x64, 0x69, 0x73, 0x63, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x71, 0x75, 0x65, 0x75, 0x65, 0x44, 0x69, 0x73, + 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x12, 0x69, 0x0a, 0x11, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x3c, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, + 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x10, 0x6f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, + 0x69, 0x6e, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x6b, 0x69, 0x6e, + 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x6c, 0x61, 0x76, 0x65, 0x4b, 0x69, + 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x75, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, + 0x05, 0x70, 0x63, 0x69, 0x69, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x63, + 0x69, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x0f, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x64, + 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x66, 0x69, + 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, + 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, + 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x15, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, + 0x69, 0x6e, 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x70, + 0x65, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x67, 0x61, 0x62, 0x69, 0x74, 0x73, 0x18, 0x17, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0d, 0x73, 0x70, 0x65, 0x65, 0x64, 0x4d, 0x65, 0x67, 0x61, 0x62, 0x69, 0x74, + 0x73, 0x12, 0x44, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x30, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, + 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x50, 0x6f, 0x72, + 0x74, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x4a, 0x0a, 0x06, 0x64, 0x75, 0x70, 0x6c, 0x65, + 0x78, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, + 0x6c, 0x70, 0x65, 0x72, 0x73, 0x44, 0x75, 0x70, 0x6c, 0x65, 0x78, 0x52, 0x06, 0x64, 0x75, 0x70, + 0x6c, 0x65, 0x78, 0x12, 0x40, 0x0a, 0x04, 0x76, 0x6c, 0x61, 0x6e, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x56, 0x4c, 0x41, 0x4e, 0x53, 0x70, 0x65, 0x63, 0x52, - 0x04, 0x76, 0x6c, 0x61, 0x6e, 0x12, 0x53, 0x0a, 0x0b, 0x62, 0x6f, 0x6e, 0x64, 0x5f, 0x6d, 0x61, - 0x73, 0x74, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, - 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, - 0x42, 0x6f, 0x6e, 0x64, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0a, - 0x62, 0x6f, 0x6e, 0x64, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x12, 0x59, 0x0a, 0x0d, 0x62, 0x72, - 0x69, 0x64, 0x67, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, - 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x4d, 0x61, 0x73, - 0x74, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0c, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x4d, + 0x04, 0x76, 0x6c, 0x61, 0x6e, 0x12, 0x59, 0x0a, 0x0d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x5f, + 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, + 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x2e, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x53, 0x70, + 0x65, 0x63, 0x52, 0x0c, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, + 0x12, 0x53, 0x0a, 0x0b, 0x62, 0x6f, 0x6e, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x18, + 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x42, 0x6f, 0x6e, 0x64, 0x4d, + 0x61, 0x73, 0x74, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0a, 0x62, 0x6f, 0x6e, 0x64, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x12, 0x4f, 0x0a, 0x09, 0x77, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, - 0x72, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, + 0x72, 0x64, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x57, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x53, 0x70, 0x65, 0x63, 0x52, 0x09, 0x77, 0x69, 0x72, - 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, - 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, - 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, - 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, - 0x65, 0x72, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x22, - 0xae, 0x0a, 0x0a, 0x0e, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, - 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x48, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, - 0x70, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x6e, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x6e, 0x64, 0x65, - 0x78, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x68, 0x61, 0x72, 0x64, 0x77, - 0x61, 0x72, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, - 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x41, 0x64, 0x64, 0x72, 0x12, 0x25, 0x0a, 0x0e, - 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x41, - 0x64, 0x64, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x74, 0x75, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x03, 0x6d, 0x74, 0x75, 0x12, 0x1d, 0x0a, 0x0a, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x64, - 0x69, 0x73, 0x63, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x71, 0x75, 0x65, 0x75, 0x65, - 0x44, 0x69, 0x73, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x6d, 0x61, 0x73, 0x74, - 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x69, 0x0a, 0x11, 0x6f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x3c, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, - 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x52, 0x10, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x6c, 0x61, 0x76, 0x65, 0x5f, - 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x6c, 0x61, 0x76, - 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x75, 0x73, 0x5f, 0x70, 0x61, 0x74, - 0x68, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x73, 0x50, 0x61, 0x74, 0x68, - 0x12, 0x14, 0x0a, 0x05, 0x70, 0x63, 0x69, 0x69, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x70, 0x63, 0x69, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, - 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x25, - 0x0a, 0x0e, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0f, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x12, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, - 0x1b, 0x0a, 0x09, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x13, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, - 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, - 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, - 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x1d, - 0x0a, 0x0a, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x16, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x25, 0x0a, - 0x0e, 0x73, 0x70, 0x65, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x67, 0x61, 0x62, 0x69, 0x74, 0x73, 0x18, - 0x17, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x73, 0x70, 0x65, 0x65, 0x64, 0x4d, 0x65, 0x67, 0x61, - 0x62, 0x69, 0x74, 0x73, 0x12, 0x44, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x18, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x30, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6e, + 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, + 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x22, 0xaa, 0x01, + 0x0a, 0x14, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x3c, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, + 0x65, 0x66, 0x69, 0x78, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x75, 0x62, + 0x6e, 0x65, 0x74, 0x73, 0x12, 0x3c, 0x0a, 0x0f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, + 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, + 0x69, 0x78, 0x52, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, + 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x22, 0xf6, 0x02, 0x0a, 0x11, 0x4e, + 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x70, 0x65, 0x63, + 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x12, 0x51, 0x0a, 0x04, 0x68, 0x6f, 0x6f, 0x6b, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x3d, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, - 0x50, 0x6f, 0x72, 0x74, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x4a, 0x0a, 0x06, 0x64, 0x75, - 0x70, 0x6c, 0x65, 0x78, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, - 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, - 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x44, 0x75, 0x70, 0x6c, 0x65, 0x78, 0x52, 0x06, - 0x64, 0x75, 0x70, 0x6c, 0x65, 0x78, 0x12, 0x40, 0x0a, 0x04, 0x76, 0x6c, 0x61, 0x6e, 0x18, 0x1a, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x56, 0x4c, 0x41, 0x4e, 0x53, 0x70, - 0x65, 0x63, 0x52, 0x04, 0x76, 0x6c, 0x61, 0x6e, 0x12, 0x59, 0x0a, 0x0d, 0x62, 0x72, 0x69, 0x64, - 0x67, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, - 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0c, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x4d, 0x61, 0x73, - 0x74, 0x65, 0x72, 0x12, 0x53, 0x0a, 0x0b, 0x62, 0x6f, 0x6e, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x74, - 0x65, 0x72, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x42, 0x6f, - 0x6e, 0x64, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0a, 0x62, 0x6f, - 0x6e, 0x64, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x12, 0x4f, 0x0a, 0x09, 0x77, 0x69, 0x72, 0x65, - 0x67, 0x75, 0x61, 0x72, 0x64, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x61, - 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, - 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x2e, 0x57, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x53, 0x70, 0x65, 0x63, 0x52, 0x09, - 0x77, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x65, 0x72, - 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x1e, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0d, 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, - 0x22, 0xaa, 0x01, 0x0a, 0x14, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x3c, 0x0a, 0x0f, 0x69, 0x6e, 0x63, - 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, - 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, - 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x3c, 0x0a, 0x0f, 0x65, 0x78, 0x63, 0x6c, 0x75, - 0x64, 0x65, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, - 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x75, - 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x22, 0xf6, 0x02, - 0x0a, 0x11, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, - 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x51, 0x0a, 0x04, 0x68, 0x6f, 0x6f, 0x6b, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3d, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, - 0x65, 0x72, 0x73, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, - 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x04, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x5d, 0x0a, 0x08, 0x70, 0x72, - 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x41, 0x2e, 0x74, - 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, - 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, - 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x52, - 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x72, 0x75, 0x6c, - 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, - 0x73, 0x12, 0x53, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x3b, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, - 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x4e, - 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x56, 0x65, 0x72, 0x64, 0x69, 0x63, 0x74, 0x52, 0x06, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x24, 0x0a, 0x10, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x43, 0x6c, 0x61, 0x6d, 0x70, 0x4d, 0x53, 0x53, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x74, - 0x75, 0x18, 0x01, 0x20, 0x01, 0x28, 0x07, 0x52, 0x03, 0x6d, 0x74, 0x75, 0x22, 0x71, 0x0a, 0x1b, - 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x74, 0x72, 0x61, 0x63, - 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x52, 0x0a, 0x06, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x3a, 0x2e, 0x74, 0x61, - 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, - 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, - 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x74, 0x72, 0x61, - 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x22, - 0x95, 0x01, 0x0a, 0x13, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x49, 0x66, 0x4e, 0x61, - 0x6d, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x55, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x74, 0x61, 0x6c, 0x6f, + 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x48, 0x6f, 0x6f, + 0x6b, 0x52, 0x04, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x5d, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x41, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, - 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x70, 0x65, 0x72, - 0x61, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x27, - 0x0a, 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xb7, 0x02, 0x0a, 0x13, 0x4e, 0x66, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x34, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, - 0x50, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, - 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x12, 0x61, 0x0a, 0x11, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, - 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, - 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x52, 0x0f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x50, 0x6f, 0x72, 0x74, 0x12, 0x6b, 0x0a, 0x16, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, - 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x14, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x72, - 0x74, 0x22, 0x49, 0x0a, 0x12, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x4c, 0x69, 0x6d, - 0x69, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x33, 0x0a, 0x16, 0x70, 0x61, 0x63, 0x6b, 0x65, - 0x74, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x52, - 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x22, 0x4a, 0x0a, 0x0c, - 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x4d, 0x61, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, - 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x61, 0x73, 0x6b, - 0x12, 0x10, 0x0a, 0x03, 0x78, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x78, - 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x5a, 0x0a, 0x11, 0x4e, 0x66, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x45, 0x0a, - 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, - 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, - 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x06, 0x72, 0x61, - 0x6e, 0x67, 0x65, 0x73, 0x22, 0xc5, 0x08, 0x0a, 0x0c, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x5e, 0x0a, 0x0f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6f, - 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, + 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, + 0x68, 0x61, 0x69, 0x6e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x52, 0x08, 0x70, 0x72, + 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x53, + 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3b, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, - 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x49, 0x66, 0x4e, 0x61, - 0x6d, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x0c, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x49, - 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x55, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x64, 0x69, 0x63, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3b, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, + 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x4e, 0x66, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x56, 0x65, 0x72, 0x64, 0x69, 0x63, 0x74, 0x52, 0x06, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x22, 0x24, 0x0a, 0x10, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, + 0x6c, 0x61, 0x6d, 0x70, 0x4d, 0x53, 0x53, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x74, 0x75, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x07, 0x52, 0x03, 0x6d, 0x74, 0x75, 0x22, 0x71, 0x0a, 0x1b, 0x4e, 0x66, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x52, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x3a, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, + 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, + 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x22, 0x95, 0x01, 0x0a, + 0x13, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x49, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x4d, + 0x61, 0x74, 0x63, 0x68, 0x12, 0x55, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, - 0x70, 0x65, 0x72, 0x73, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x56, 0x65, 0x72, 0x64, - 0x69, 0x63, 0x74, 0x52, 0x07, 0x76, 0x65, 0x72, 0x64, 0x69, 0x63, 0x74, 0x12, 0x4f, 0x0a, 0x0a, - 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x30, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x4d, 0x61, - 0x72, 0x6b, 0x52, 0x09, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x61, 0x72, 0x6b, 0x12, 0x4b, 0x0a, - 0x08, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x30, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x4d, 0x61, 0x72, - 0x6b, 0x52, 0x07, 0x73, 0x65, 0x74, 0x4d, 0x61, 0x72, 0x6b, 0x12, 0x6a, 0x0a, 0x14, 0x6d, 0x61, - 0x74, 0x63, 0x68, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4d, 0x61, 0x74, - 0x63, 0x68, 0x52, 0x12, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x74, 0x0a, 0x19, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, - 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x74, 0x61, 0x6c, 0x6f, + 0x70, 0x65, 0x72, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x22, 0xb7, 0x02, 0x0a, 0x13, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x34, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x50, 0x0a, 0x08, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, + 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, + 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x61, + 0x0a, 0x11, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, + 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, - 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x52, 0x17, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x5a, 0x0a, 0x0c, - 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x34, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x4c, 0x61, 0x79, 0x65, 0x72, 0x34, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x0b, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x34, 0x12, 0x5e, 0x0a, 0x0f, 0x6d, 0x61, 0x74, 0x63, - 0x68, 0x5f, 0x69, 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x37, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x52, 0x0f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, + 0x74, 0x12, 0x6b, 0x0a, 0x16, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, - 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x49, - 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x0c, 0x6d, 0x61, 0x74, 0x63, - 0x68, 0x49, 0x49, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x51, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x6d, - 0x70, 0x5f, 0x6d, 0x73, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x61, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x50, + 0x6f, 0x72, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x14, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x44, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x49, + 0x0a, 0x12, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x4d, + 0x61, 0x74, 0x63, 0x68, 0x12, 0x33, 0x0a, 0x16, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x72, + 0x61, 0x74, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x61, 0x74, 0x65, + 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x22, 0x4a, 0x0a, 0x0c, 0x4e, 0x66, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x4d, 0x61, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x73, + 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x61, 0x73, 0x6b, 0x12, 0x10, 0x0a, + 0x03, 0x78, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x78, 0x6f, 0x72, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x5a, 0x0a, 0x11, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x50, 0x6f, 0x72, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x45, 0x0a, 0x06, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x6c, + 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, + 0x50, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x22, 0xc5, 0x08, 0x0a, 0x0c, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x75, + 0x6c, 0x65, 0x12, 0x5e, 0x0a, 0x0f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6f, 0x5f, 0x69, 0x66, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6c, 0x61, 0x6d, 0x70, 0x4d, 0x53, - 0x53, 0x52, 0x08, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x73, 0x12, 0x57, 0x0a, 0x0b, 0x6d, - 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x36, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x4c, 0x69, - 0x6d, 0x69, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x0a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4c, - 0x69, 0x6d, 0x69, 0x74, 0x12, 0x73, 0x0a, 0x15, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6f, - 0x6e, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, + 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x49, 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x4d, + 0x61, 0x74, 0x63, 0x68, 0x52, 0x0c, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4f, 0x49, 0x66, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x55, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x64, 0x69, 0x63, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x3b, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4d, - 0x61, 0x74, 0x63, 0x68, 0x52, 0x13, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x74, - 0x72, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x6e, 0x6f, - 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0b, 0x61, 0x6e, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x93, 0x01, 0x0a, - 0x15, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x3c, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, - 0x65, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, - 0x65, 0x66, 0x69, 0x78, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x75, 0x62, - 0x6e, 0x65, 0x74, 0x73, 0x12, 0x3c, 0x0a, 0x0f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, - 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, - 0x69, 0x78, 0x52, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, - 0x74, 0x73, 0x22, 0x44, 0x0a, 0x0f, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x31, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x09, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0xd7, 0x03, 0x0a, 0x10, 0x4f, 0x70, 0x65, - 0x72, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x4d, 0x0a, - 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, - 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x6f, 0x72, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, - 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x6c, 0x69, 0x6e, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, - 0x75, 0x69, 0x72, 0x65, 0x5f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x55, 0x70, 0x12, 0x4b, 0x0a, 0x05, 0x64, 0x68, 0x63, 0x70, - 0x34, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x44, 0x48, 0x43, - 0x50, 0x34, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, - 0x64, 0x68, 0x63, 0x70, 0x34, 0x12, 0x4b, 0x0a, 0x05, 0x64, 0x68, 0x63, 0x70, 0x36, 0x18, 0x05, + 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, + 0x73, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x56, 0x65, 0x72, 0x64, 0x69, 0x63, 0x74, + 0x52, 0x07, 0x76, 0x65, 0x72, 0x64, 0x69, 0x63, 0x74, 0x12, 0x4f, 0x0a, 0x0a, 0x6d, 0x61, 0x74, + 0x63, 0x68, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, + 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x4d, 0x61, 0x72, 0x6b, 0x52, + 0x09, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x61, 0x72, 0x6b, 0x12, 0x4b, 0x0a, 0x08, 0x73, 0x65, + 0x74, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, + 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x4d, 0x61, 0x72, 0x6b, 0x52, 0x07, + 0x73, 0x65, 0x74, 0x4d, 0x61, 0x72, 0x6b, 0x12, 0x6a, 0x0a, 0x14, 0x6d, 0x61, 0x74, 0x63, 0x68, + 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, + 0x12, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x74, 0x0a, 0x19, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x52, 0x17, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x5a, 0x0a, 0x0c, 0x6d, 0x61, 0x74, + 0x63, 0x68, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x34, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x37, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x4c, 0x61, 0x79, + 0x65, 0x72, 0x34, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x0b, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4c, + 0x61, 0x79, 0x65, 0x72, 0x34, 0x12, 0x5e, 0x0a, 0x0f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x69, + 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, + 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x49, 0x66, 0x4e, 0x61, + 0x6d, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x0c, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x49, 0x49, + 0x66, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x51, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x5f, 0x6d, + 0x73, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, + 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6c, 0x61, 0x6d, 0x70, 0x4d, 0x53, 0x53, 0x52, 0x08, + 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x73, 0x12, 0x57, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x63, + 0x68, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, + 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, + 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x0a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x69, 0x6d, 0x69, + 0x74, 0x12, 0x73, 0x0a, 0x15, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x74, + 0x72, 0x61, 0x63, 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x3f, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x4e, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x43, 0x6f, + 0x6e, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x74, 0x63, + 0x68, 0x52, 0x13, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x74, 0x72, 0x61, 0x63, + 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x6e, 0x6f, 0x6e, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x6e, + 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x93, 0x01, 0x0a, 0x15, 0x4e, 0x6f, + 0x64, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x53, + 0x70, 0x65, 0x63, 0x12, 0x3c, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x73, + 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, + 0x78, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, + 0x73, 0x12, 0x3c, 0x0a, 0x0f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x73, 0x75, 0x62, + 0x6e, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, + 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x22, + 0x44, 0x0a, 0x0f, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x70, + 0x65, 0x63, 0x12, 0x31, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, + 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0xd7, 0x03, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x4d, 0x0a, 0x08, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x74, + 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, + 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, + 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x69, 0x6e, + 0x6b, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x69, + 0x6e, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x5f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x55, 0x70, 0x12, 0x4b, 0x0a, 0x05, 0x64, 0x68, 0x63, 0x70, 0x34, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x44, 0x48, 0x43, 0x50, 0x36, 0x4f, + 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x44, 0x48, 0x43, 0x50, 0x34, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, 0x64, 0x68, 0x63, - 0x70, 0x36, 0x12, 0x45, 0x0a, 0x03, 0x76, 0x69, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x33, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x70, 0x34, 0x12, 0x4b, 0x0a, 0x05, 0x64, 0x68, 0x63, 0x70, 0x36, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x44, 0x48, 0x43, 0x50, 0x36, 0x4f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, 0x64, 0x68, 0x63, 0x70, 0x36, 0x12, + 0x45, 0x0a, 0x03, 0x76, 0x69, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, + 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x2e, 0x56, 0x49, 0x50, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, + 0x63, 0x52, 0x03, 0x76, 0x69, 0x70, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, + 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, + 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, + 0x65, 0x72, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x22, + 0x2b, 0x0a, 0x09, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x6c, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x07, 0x52, 0x02, 0x6c, 0x6f, 0x12, 0x0e, 0x0a, 0x02, + 0x68, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x07, 0x52, 0x02, 0x68, 0x69, 0x22, 0x90, 0x02, 0x0a, + 0x0d, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x35, + 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x2b, 0x0a, 0x11, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, + 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x10, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, + 0x6c, 0x64, 0x12, 0x42, 0x0a, 0x03, 0x74, 0x63, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x30, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x56, 0x49, 0x50, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, - 0x53, 0x70, 0x65, 0x63, 0x52, 0x03, 0x76, 0x69, 0x70, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, - 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, - 0x65, 0x72, 0x22, 0x2b, 0x0a, 0x09, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, - 0x0e, 0x0a, 0x02, 0x6c, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x07, 0x52, 0x02, 0x6c, 0x6f, 0x12, - 0x0e, 0x0a, 0x02, 0x68, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x07, 0x52, 0x02, 0x68, 0x69, 0x22, - 0x90, 0x02, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, - 0x63, 0x12, 0x35, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x2b, 0x0a, 0x11, 0x66, 0x61, 0x69, 0x6c, - 0x75, 0x72, 0x65, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x10, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x54, 0x68, 0x72, 0x65, - 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x42, 0x0a, 0x03, 0x74, 0x63, 0x70, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x54, 0x43, 0x50, 0x50, 0x72, 0x6f, 0x62, 0x65, - 0x53, 0x70, 0x65, 0x63, 0x52, 0x03, 0x74, 0x63, 0x70, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, - 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, - 0x65, 0x72, 0x22, 0x4a, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, - 0x1d, 0x0a, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x9b, - 0x01, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x53, - 0x70, 0x65, 0x63, 0x12, 0x2e, 0x0a, 0x0b, 0x64, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x0a, 0x64, 0x6e, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x73, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, - 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, - 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x22, 0x44, 0x0a, 0x12, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, - 0x65, 0x63, 0x12, 0x2e, 0x0a, 0x0b, 0x64, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x0a, 0x64, 0x6e, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x73, 0x22, 0xde, 0x05, 0x0a, 0x0d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x53, 0x70, 0x65, 0x63, + 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x54, 0x43, 0x50, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x70, 0x65, + 0x63, 0x52, 0x03, 0x74, 0x63, 0x70, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, + 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, + 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, + 0x65, 0x72, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x22, + 0x4a, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, + 0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x9b, 0x01, 0x0a, 0x10, + 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, + 0x12, 0x2e, 0x0a, 0x0b, 0x64, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, + 0x65, 0x74, 0x49, 0x50, 0x52, 0x0a, 0x64, 0x6e, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, + 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x0b, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x22, 0x44, 0x0a, 0x12, 0x52, 0x65, 0x73, + 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, + 0x2e, 0x0a, 0x0b, 0x64, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, + 0x74, 0x49, 0x50, 0x52, 0x0a, 0x64, 0x6e, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, + 0xde, 0x05, 0x0a, 0x0d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, + 0x63, 0x12, 0x4a, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, + 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x46, + 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x12, 0x35, 0x0a, + 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, + 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, + 0x74, 0x49, 0x50, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x07, 0x67, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x07, 0x67, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x12, 0x22, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x75, 0x74, + 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x05, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, + 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x52, 0x05, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x12, 0x47, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, + 0x73, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x49, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, 0x2e, 0x74, 0x61, + 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, + 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, + 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x55, + 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x39, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, + 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, + 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, + 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, + 0x72, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x10, + 0x0a, 0x03, 0x6d, 0x74, 0x75, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6d, 0x74, 0x75, + 0x22, 0xad, 0x05, 0x0a, 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x4a, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, @@ -4235,190 +4294,143 @@ var file_resource_definitions_network_network_proto_rawDesc = []byte{ 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x07, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x07, - 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x22, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x5f, 0x6c, - 0x69, 0x6e, 0x6b, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x6f, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x05, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x74, 0x61, 0x6c, - 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, - 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, - 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, - 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x47, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, - 0x70, 0x65, 0x72, 0x73, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, - 0x12, 0x49, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, - 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, - 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, - 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, - 0x6c, 0x61, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, - 0x73, 0x12, 0x55, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, - 0x73, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, - 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, - 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, - 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, - 0x61, 0x79, 0x65, 0x72, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, - 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x74, 0x75, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, - 0x6d, 0x74, 0x75, 0x22, 0xad, 0x05, 0x0a, 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x4a, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, - 0x6c, 0x70, 0x65, 0x72, 0x73, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x52, 0x06, 0x66, 0x61, 0x6d, - 0x69, 0x6c, 0x79, 0x12, 0x35, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x0b, 0x64, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x12, 0x27, 0x0a, 0x07, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, - 0x50, 0x52, 0x07, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x75, - 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0c, 0x6f, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x49, 0x6e, 0x64, 0x65, 0x78, - 0x12, 0x22, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x6b, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x05, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, - 0x73, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, - 0x12, 0x47, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, - 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x53, 0x63, 0x6f, - 0x70, 0x65, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x49, 0x0a, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, - 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x55, 0x0a, 0x08, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x74, + 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x75, 0x74, 0x5f, 0x6c, + 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0c, 0x6f, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x22, 0x0a, + 0x0d, 0x6f, 0x75, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x4e, 0x0a, 0x05, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x38, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, + 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x47, 0x0a, + 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, - 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x74, 0x75, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, - 0x6d, 0x74, 0x75, 0x22, 0x23, 0x0a, 0x07, 0x53, 0x54, 0x50, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, - 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xaf, 0x01, 0x0a, 0x0a, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, 0x2d, 0x0a, 0x12, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x72, 0x65, 0x61, - 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x68, - 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0d, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x61, - 0x64, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x74, 0x63, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, - 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, 0x74, 0x63, - 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x61, 0x64, 0x79, 0x22, 0x5f, 0x0a, 0x0c, 0x54, 0x43, - 0x50, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, - 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, - 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x8e, 0x01, 0x0a, 0x12, - 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, - 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x74, 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x74, 0x70, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x73, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, + 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x52, + 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x49, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, + 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x55, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, - 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x22, 0x37, 0x0a, 0x14, - 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x74, 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x74, 0x70, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, 0x6e, 0x0a, 0x13, 0x56, 0x49, 0x50, 0x45, 0x71, 0x75, 0x69, - 0x6e, 0x69, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1d, 0x0a, 0x0a, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x69, 0x5f, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x69, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x68, 0x0a, 0x0d, 0x56, 0x49, 0x50, 0x48, 0x43, 0x6c, 0x6f, - 0x75, 0x64, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x69, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x69, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, - 0x81, 0x02, 0x0a, 0x0f, 0x56, 0x49, 0x50, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x53, - 0x70, 0x65, 0x63, 0x12, 0x1d, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x02, - 0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x67, 0x72, 0x61, 0x74, 0x75, 0x69, 0x74, 0x6f, 0x75, 0x73, - 0x5f, 0x61, 0x72, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x67, 0x72, 0x61, 0x74, - 0x75, 0x69, 0x74, 0x6f, 0x75, 0x73, 0x41, 0x72, 0x70, 0x12, 0x5c, 0x0a, 0x0d, 0x65, 0x71, 0x75, - 0x69, 0x6e, 0x69, 0x78, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x37, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x56, 0x49, 0x50, 0x45, 0x71, 0x75, 0x69, 0x6e, 0x69, 0x78, - 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0c, 0x65, 0x71, 0x75, 0x69, 0x6e, - 0x69, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x12, 0x4a, 0x0a, 0x07, 0x68, 0x5f, 0x63, 0x6c, 0x6f, - 0x75, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x56, 0x49, - 0x50, 0x48, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x70, 0x65, 0x63, 0x52, 0x06, 0x68, 0x43, 0x6c, - 0x6f, 0x75, 0x64, 0x22, 0x72, 0x0a, 0x08, 0x56, 0x4c, 0x41, 0x4e, 0x53, 0x70, 0x65, 0x63, 0x12, - 0x10, 0x0a, 0x03, 0x76, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x07, 0x52, 0x03, 0x76, 0x69, - 0x64, 0x12, 0x54, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, - 0x73, 0x56, 0x4c, 0x41, 0x4e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x84, 0x02, 0x0a, 0x0d, 0x57, 0x69, 0x72, 0x65, - 0x67, 0x75, 0x61, 0x72, 0x64, 0x50, 0x65, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x73, - 0x68, 0x61, 0x72, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x70, 0x72, 0x65, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, - 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x5d, 0x0a, 0x1d, 0x70, 0x65, 0x72, - 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, - 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x1b, 0x70, 0x65, 0x72, - 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x34, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x6f, - 0x77, 0x65, 0x64, 0x5f, 0x69, 0x70, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, - 0x69, 0x78, 0x52, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x49, 0x70, 0x73, 0x22, 0xde, - 0x01, 0x0a, 0x0d, 0x57, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x53, 0x70, 0x65, 0x63, - 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, - 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, - 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x50, 0x6f, 0x72, - 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x72, 0x65, 0x77, 0x61, 0x6c, 0x6c, 0x5f, 0x6d, 0x61, - 0x72, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x66, 0x69, 0x72, 0x65, 0x77, 0x61, - 0x6c, 0x6c, 0x4d, 0x61, 0x72, 0x6b, 0x12, 0x47, 0x0a, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, - 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, + 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x10, + 0x0a, 0x03, 0x6d, 0x74, 0x75, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6d, 0x74, 0x75, + 0x22, 0x23, 0x0a, 0x07, 0x53, 0x54, 0x50, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xaf, 0x01, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x53, 0x70, 0x65, 0x63, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, + 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x74, 0x79, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x68, 0x6f, 0x73, 0x74, + 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0d, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, + 0x26, 0x0a, 0x0f, 0x65, 0x74, 0x63, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x61, + 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, 0x74, 0x63, 0x46, 0x69, 0x6c, + 0x65, 0x73, 0x52, 0x65, 0x61, 0x64, 0x79, 0x22, 0x5f, 0x0a, 0x0c, 0x54, 0x43, 0x50, 0x50, 0x72, + 0x6f, 0x62, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x8e, 0x01, 0x0a, 0x12, 0x54, 0x69, 0x6d, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, + 0x1f, 0x0a, 0x0b, 0x6e, 0x74, 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x74, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, + 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x0b, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x22, 0x37, 0x0a, 0x14, 0x54, 0x69, 0x6d, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, + 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x74, 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x74, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x73, 0x22, 0x6e, 0x0a, 0x13, 0x56, 0x49, 0x50, 0x45, 0x71, 0x75, 0x69, 0x6e, 0x69, 0x78, + 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x69, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x69, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x22, 0x68, 0x0a, 0x0d, 0x56, 0x49, 0x50, 0x48, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, + 0x70, 0x65, 0x63, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, + 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x69, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x69, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x81, 0x02, 0x0a, + 0x0f, 0x56, 0x49, 0x50, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, + 0x12, 0x1d, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x02, 0x69, 0x70, 0x12, + 0x25, 0x0a, 0x0e, 0x67, 0x72, 0x61, 0x74, 0x75, 0x69, 0x74, 0x6f, 0x75, 0x73, 0x5f, 0x61, 0x72, + 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x67, 0x72, 0x61, 0x74, 0x75, 0x69, 0x74, + 0x6f, 0x75, 0x73, 0x41, 0x72, 0x70, 0x12, 0x5c, 0x0a, 0x0d, 0x65, 0x71, 0x75, 0x69, 0x6e, 0x69, + 0x78, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, + 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x2e, 0x56, 0x49, 0x50, 0x45, 0x71, 0x75, 0x69, 0x6e, 0x69, 0x78, 0x4d, 0x65, 0x74, + 0x61, 0x6c, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0c, 0x65, 0x71, 0x75, 0x69, 0x6e, 0x69, 0x78, 0x4d, + 0x65, 0x74, 0x61, 0x6c, 0x12, 0x4a, 0x0a, 0x07, 0x68, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x57, 0x69, 0x72, 0x65, 0x67, - 0x75, 0x61, 0x72, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x42, - 0x78, 0x0a, 0x2a, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5a, 0x4a, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, - 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, - 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x56, 0x49, 0x50, 0x48, 0x43, + 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x70, 0x65, 0x63, 0x52, 0x06, 0x68, 0x43, 0x6c, 0x6f, 0x75, 0x64, + 0x22, 0x72, 0x0a, 0x08, 0x56, 0x4c, 0x41, 0x4e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x10, 0x0a, 0x03, + 0x76, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x07, 0x52, 0x03, 0x76, 0x69, 0x64, 0x12, 0x54, + 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x38, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, + 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x56, 0x4c, + 0x41, 0x4e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x84, 0x02, 0x0a, 0x0d, 0x57, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, + 0x72, 0x64, 0x50, 0x65, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x73, 0x68, 0x61, 0x72, + 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, + 0x65, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, + 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, + 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x5d, 0x0a, 0x1d, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x1b, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x34, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, + 0x5f, 0x69, 0x70, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, + 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x49, 0x70, 0x73, 0x22, 0xde, 0x01, 0x0a, 0x0d, + 0x57, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, + 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1d, + 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1f, 0x0a, + 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0a, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x23, + 0x0a, 0x0d, 0x66, 0x69, 0x72, 0x65, 0x77, 0x61, 0x6c, 0x6c, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x66, 0x69, 0x72, 0x65, 0x77, 0x61, 0x6c, 0x6c, 0x4d, + 0x61, 0x72, 0x6b, 0x12, 0x47, 0x0a, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, + 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x57, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, 0x72, + 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x42, 0x78, 0x0a, 0x2a, + 0x64, 0x65, 0x76, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x6c, 0x61, 0x62, + 0x73, 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x61, 0x63, 0x68, + 0x69, 0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -4538,91 +4550,92 @@ var file_resource_definitions_network_network_proto_depIdxs = []int32{ 6, // 20: talos.resource.definitions.network.BridgeMasterSpec.vlan:type_name -> talos.resource.definitions.network.BridgeVLANSpec 61, // 21: talos.resource.definitions.network.HostDNSConfigSpec.listen_addresses:type_name -> common.NetIPPort 52, // 22: talos.resource.definitions.network.HostDNSConfigSpec.service_host_dns_address:type_name -> common.NetIP - 51, // 23: talos.resource.definitions.network.HostnameSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 62, // 24: talos.resource.definitions.network.LinkSpecSpec.type:type_name -> talos.resource.definitions.enums.NethelpersLinkType - 3, // 25: talos.resource.definitions.network.LinkSpecSpec.bond_slave:type_name -> talos.resource.definitions.network.BondSlave - 5, // 26: talos.resource.definitions.network.LinkSpecSpec.bridge_slave:type_name -> talos.resource.definitions.network.BridgeSlave - 45, // 27: talos.resource.definitions.network.LinkSpecSpec.vlan:type_name -> talos.resource.definitions.network.VLANSpec - 2, // 28: talos.resource.definitions.network.LinkSpecSpec.bond_master:type_name -> talos.resource.definitions.network.BondMasterSpec - 4, // 29: talos.resource.definitions.network.LinkSpecSpec.bridge_master:type_name -> talos.resource.definitions.network.BridgeMasterSpec - 47, // 30: talos.resource.definitions.network.LinkSpecSpec.wireguard:type_name -> talos.resource.definitions.network.WireguardSpec - 51, // 31: talos.resource.definitions.network.LinkSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 62, // 32: talos.resource.definitions.network.LinkStatusSpec.type:type_name -> talos.resource.definitions.enums.NethelpersLinkType - 63, // 33: talos.resource.definitions.network.LinkStatusSpec.operational_state:type_name -> talos.resource.definitions.enums.NethelpersOperationalState - 64, // 34: talos.resource.definitions.network.LinkStatusSpec.port:type_name -> talos.resource.definitions.enums.NethelpersPort - 65, // 35: talos.resource.definitions.network.LinkStatusSpec.duplex:type_name -> talos.resource.definitions.enums.NethelpersDuplex - 45, // 36: talos.resource.definitions.network.LinkStatusSpec.vlan:type_name -> talos.resource.definitions.network.VLANSpec - 4, // 37: talos.resource.definitions.network.LinkStatusSpec.bridge_master:type_name -> talos.resource.definitions.network.BridgeMasterSpec - 2, // 38: talos.resource.definitions.network.LinkStatusSpec.bond_master:type_name -> talos.resource.definitions.network.BondMasterSpec - 47, // 39: talos.resource.definitions.network.LinkStatusSpec.wireguard:type_name -> talos.resource.definitions.network.WireguardSpec - 48, // 40: talos.resource.definitions.network.NfTablesAddressMatch.include_subnets:type_name -> common.NetIPPrefix - 48, // 41: talos.resource.definitions.network.NfTablesAddressMatch.exclude_subnets:type_name -> common.NetIPPrefix - 66, // 42: talos.resource.definitions.network.NfTablesChainSpec.hook:type_name -> talos.resource.definitions.enums.NethelpersNfTablesChainHook - 67, // 43: talos.resource.definitions.network.NfTablesChainSpec.priority:type_name -> talos.resource.definitions.enums.NethelpersNfTablesChainPriority - 26, // 44: talos.resource.definitions.network.NfTablesChainSpec.rules:type_name -> talos.resource.definitions.network.NfTablesRule - 68, // 45: talos.resource.definitions.network.NfTablesChainSpec.policy:type_name -> talos.resource.definitions.enums.NethelpersNfTablesVerdict - 69, // 46: talos.resource.definitions.network.NfTablesConntrackStateMatch.states:type_name -> talos.resource.definitions.enums.NethelpersConntrackState - 70, // 47: talos.resource.definitions.network.NfTablesIfNameMatch.operator:type_name -> talos.resource.definitions.enums.NethelpersMatchOperator - 71, // 48: talos.resource.definitions.network.NfTablesLayer4Match.protocol:type_name -> talos.resource.definitions.enums.NethelpersProtocol - 25, // 49: talos.resource.definitions.network.NfTablesLayer4Match.match_source_port:type_name -> talos.resource.definitions.network.NfTablesPortMatch - 25, // 50: talos.resource.definitions.network.NfTablesLayer4Match.match_destination_port:type_name -> talos.resource.definitions.network.NfTablesPortMatch - 30, // 51: talos.resource.definitions.network.NfTablesPortMatch.ranges:type_name -> talos.resource.definitions.network.PortRange - 21, // 52: talos.resource.definitions.network.NfTablesRule.match_o_if_name:type_name -> talos.resource.definitions.network.NfTablesIfNameMatch - 68, // 53: talos.resource.definitions.network.NfTablesRule.verdict:type_name -> talos.resource.definitions.enums.NethelpersNfTablesVerdict - 24, // 54: talos.resource.definitions.network.NfTablesRule.match_mark:type_name -> talos.resource.definitions.network.NfTablesMark - 24, // 55: talos.resource.definitions.network.NfTablesRule.set_mark:type_name -> talos.resource.definitions.network.NfTablesMark - 17, // 56: talos.resource.definitions.network.NfTablesRule.match_source_address:type_name -> talos.resource.definitions.network.NfTablesAddressMatch - 17, // 57: talos.resource.definitions.network.NfTablesRule.match_destination_address:type_name -> talos.resource.definitions.network.NfTablesAddressMatch - 22, // 58: talos.resource.definitions.network.NfTablesRule.match_layer4:type_name -> talos.resource.definitions.network.NfTablesLayer4Match - 21, // 59: talos.resource.definitions.network.NfTablesRule.match_i_if_name:type_name -> talos.resource.definitions.network.NfTablesIfNameMatch - 19, // 60: talos.resource.definitions.network.NfTablesRule.clamp_mss:type_name -> talos.resource.definitions.network.NfTablesClampMSS - 23, // 61: talos.resource.definitions.network.NfTablesRule.match_limit:type_name -> talos.resource.definitions.network.NfTablesLimitMatch - 20, // 62: talos.resource.definitions.network.NfTablesRule.match_conntrack_state:type_name -> talos.resource.definitions.network.NfTablesConntrackStateMatch - 48, // 63: talos.resource.definitions.network.NodeAddressFilterSpec.include_subnets:type_name -> common.NetIPPrefix - 48, // 64: talos.resource.definitions.network.NodeAddressFilterSpec.exclude_subnets:type_name -> common.NetIPPrefix - 48, // 65: talos.resource.definitions.network.NodeAddressSpec.addresses:type_name -> common.NetIPPrefix - 72, // 66: talos.resource.definitions.network.OperatorSpecSpec.operator:type_name -> talos.resource.definitions.enums.NetworkOperator - 7, // 67: talos.resource.definitions.network.OperatorSpecSpec.dhcp4:type_name -> talos.resource.definitions.network.DHCP4OperatorSpec - 8, // 68: talos.resource.definitions.network.OperatorSpecSpec.dhcp6:type_name -> talos.resource.definitions.network.DHCP6OperatorSpec - 44, // 69: talos.resource.definitions.network.OperatorSpecSpec.vip:type_name -> talos.resource.definitions.network.VIPOperatorSpec - 51, // 70: talos.resource.definitions.network.OperatorSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 73, // 71: talos.resource.definitions.network.ProbeSpecSpec.interval:type_name -> google.protobuf.Duration - 39, // 72: talos.resource.definitions.network.ProbeSpecSpec.tcp:type_name -> talos.resource.definitions.network.TCPProbeSpec - 51, // 73: talos.resource.definitions.network.ProbeSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 52, // 74: talos.resource.definitions.network.ResolverSpecSpec.dns_servers:type_name -> common.NetIP - 51, // 75: talos.resource.definitions.network.ResolverSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 52, // 76: talos.resource.definitions.network.ResolverStatusSpec.dns_servers:type_name -> common.NetIP - 49, // 77: talos.resource.definitions.network.RouteSpecSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily - 48, // 78: talos.resource.definitions.network.RouteSpecSpec.destination:type_name -> common.NetIPPrefix - 52, // 79: talos.resource.definitions.network.RouteSpecSpec.source:type_name -> common.NetIP - 52, // 80: talos.resource.definitions.network.RouteSpecSpec.gateway:type_name -> common.NetIP - 74, // 81: talos.resource.definitions.network.RouteSpecSpec.table:type_name -> talos.resource.definitions.enums.NethelpersRoutingTable - 50, // 82: talos.resource.definitions.network.RouteSpecSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope - 75, // 83: talos.resource.definitions.network.RouteSpecSpec.type:type_name -> talos.resource.definitions.enums.NethelpersRouteType - 76, // 84: talos.resource.definitions.network.RouteSpecSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersRouteProtocol - 51, // 85: talos.resource.definitions.network.RouteSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 49, // 86: talos.resource.definitions.network.RouteStatusSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily - 48, // 87: talos.resource.definitions.network.RouteStatusSpec.destination:type_name -> common.NetIPPrefix - 52, // 88: talos.resource.definitions.network.RouteStatusSpec.source:type_name -> common.NetIP - 52, // 89: talos.resource.definitions.network.RouteStatusSpec.gateway:type_name -> common.NetIP - 74, // 90: talos.resource.definitions.network.RouteStatusSpec.table:type_name -> talos.resource.definitions.enums.NethelpersRoutingTable - 50, // 91: talos.resource.definitions.network.RouteStatusSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope - 75, // 92: talos.resource.definitions.network.RouteStatusSpec.type:type_name -> talos.resource.definitions.enums.NethelpersRouteType - 76, // 93: talos.resource.definitions.network.RouteStatusSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersRouteProtocol - 73, // 94: talos.resource.definitions.network.TCPProbeSpec.timeout:type_name -> google.protobuf.Duration - 51, // 95: talos.resource.definitions.network.TimeServerSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 52, // 96: talos.resource.definitions.network.VIPOperatorSpec.ip:type_name -> common.NetIP - 42, // 97: talos.resource.definitions.network.VIPOperatorSpec.equinix_metal:type_name -> talos.resource.definitions.network.VIPEquinixMetalSpec - 43, // 98: talos.resource.definitions.network.VIPOperatorSpec.h_cloud:type_name -> talos.resource.definitions.network.VIPHCloudSpec - 77, // 99: talos.resource.definitions.network.VLANSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersVLANProtocol - 73, // 100: talos.resource.definitions.network.WireguardPeer.persistent_keepalive_interval:type_name -> google.protobuf.Duration - 48, // 101: talos.resource.definitions.network.WireguardPeer.allowed_ips:type_name -> common.NetIPPrefix - 46, // 102: talos.resource.definitions.network.WireguardSpec.peers:type_name -> talos.resource.definitions.network.WireguardPeer - 103, // [103:103] is the sub-list for method output_type - 103, // [103:103] is the sub-list for method input_type - 103, // [103:103] is the sub-list for extension type_name - 103, // [103:103] is the sub-list for extension extendee - 0, // [0:103] is the sub-list for field type_name + 52, // 23: talos.resource.definitions.network.HostDNSConfigSpec.service_host_dns_address_v6:type_name -> common.NetIP + 51, // 24: talos.resource.definitions.network.HostnameSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 62, // 25: talos.resource.definitions.network.LinkSpecSpec.type:type_name -> talos.resource.definitions.enums.NethelpersLinkType + 3, // 26: talos.resource.definitions.network.LinkSpecSpec.bond_slave:type_name -> talos.resource.definitions.network.BondSlave + 5, // 27: talos.resource.definitions.network.LinkSpecSpec.bridge_slave:type_name -> talos.resource.definitions.network.BridgeSlave + 45, // 28: talos.resource.definitions.network.LinkSpecSpec.vlan:type_name -> talos.resource.definitions.network.VLANSpec + 2, // 29: talos.resource.definitions.network.LinkSpecSpec.bond_master:type_name -> talos.resource.definitions.network.BondMasterSpec + 4, // 30: talos.resource.definitions.network.LinkSpecSpec.bridge_master:type_name -> talos.resource.definitions.network.BridgeMasterSpec + 47, // 31: talos.resource.definitions.network.LinkSpecSpec.wireguard:type_name -> talos.resource.definitions.network.WireguardSpec + 51, // 32: talos.resource.definitions.network.LinkSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 62, // 33: talos.resource.definitions.network.LinkStatusSpec.type:type_name -> talos.resource.definitions.enums.NethelpersLinkType + 63, // 34: talos.resource.definitions.network.LinkStatusSpec.operational_state:type_name -> talos.resource.definitions.enums.NethelpersOperationalState + 64, // 35: talos.resource.definitions.network.LinkStatusSpec.port:type_name -> talos.resource.definitions.enums.NethelpersPort + 65, // 36: talos.resource.definitions.network.LinkStatusSpec.duplex:type_name -> talos.resource.definitions.enums.NethelpersDuplex + 45, // 37: talos.resource.definitions.network.LinkStatusSpec.vlan:type_name -> talos.resource.definitions.network.VLANSpec + 4, // 38: talos.resource.definitions.network.LinkStatusSpec.bridge_master:type_name -> talos.resource.definitions.network.BridgeMasterSpec + 2, // 39: talos.resource.definitions.network.LinkStatusSpec.bond_master:type_name -> talos.resource.definitions.network.BondMasterSpec + 47, // 40: talos.resource.definitions.network.LinkStatusSpec.wireguard:type_name -> talos.resource.definitions.network.WireguardSpec + 48, // 41: talos.resource.definitions.network.NfTablesAddressMatch.include_subnets:type_name -> common.NetIPPrefix + 48, // 42: talos.resource.definitions.network.NfTablesAddressMatch.exclude_subnets:type_name -> common.NetIPPrefix + 66, // 43: talos.resource.definitions.network.NfTablesChainSpec.hook:type_name -> talos.resource.definitions.enums.NethelpersNfTablesChainHook + 67, // 44: talos.resource.definitions.network.NfTablesChainSpec.priority:type_name -> talos.resource.definitions.enums.NethelpersNfTablesChainPriority + 26, // 45: talos.resource.definitions.network.NfTablesChainSpec.rules:type_name -> talos.resource.definitions.network.NfTablesRule + 68, // 46: talos.resource.definitions.network.NfTablesChainSpec.policy:type_name -> talos.resource.definitions.enums.NethelpersNfTablesVerdict + 69, // 47: talos.resource.definitions.network.NfTablesConntrackStateMatch.states:type_name -> talos.resource.definitions.enums.NethelpersConntrackState + 70, // 48: talos.resource.definitions.network.NfTablesIfNameMatch.operator:type_name -> talos.resource.definitions.enums.NethelpersMatchOperator + 71, // 49: talos.resource.definitions.network.NfTablesLayer4Match.protocol:type_name -> talos.resource.definitions.enums.NethelpersProtocol + 25, // 50: talos.resource.definitions.network.NfTablesLayer4Match.match_source_port:type_name -> talos.resource.definitions.network.NfTablesPortMatch + 25, // 51: talos.resource.definitions.network.NfTablesLayer4Match.match_destination_port:type_name -> talos.resource.definitions.network.NfTablesPortMatch + 30, // 52: talos.resource.definitions.network.NfTablesPortMatch.ranges:type_name -> talos.resource.definitions.network.PortRange + 21, // 53: talos.resource.definitions.network.NfTablesRule.match_o_if_name:type_name -> talos.resource.definitions.network.NfTablesIfNameMatch + 68, // 54: talos.resource.definitions.network.NfTablesRule.verdict:type_name -> talos.resource.definitions.enums.NethelpersNfTablesVerdict + 24, // 55: talos.resource.definitions.network.NfTablesRule.match_mark:type_name -> talos.resource.definitions.network.NfTablesMark + 24, // 56: talos.resource.definitions.network.NfTablesRule.set_mark:type_name -> talos.resource.definitions.network.NfTablesMark + 17, // 57: talos.resource.definitions.network.NfTablesRule.match_source_address:type_name -> talos.resource.definitions.network.NfTablesAddressMatch + 17, // 58: talos.resource.definitions.network.NfTablesRule.match_destination_address:type_name -> talos.resource.definitions.network.NfTablesAddressMatch + 22, // 59: talos.resource.definitions.network.NfTablesRule.match_layer4:type_name -> talos.resource.definitions.network.NfTablesLayer4Match + 21, // 60: talos.resource.definitions.network.NfTablesRule.match_i_if_name:type_name -> talos.resource.definitions.network.NfTablesIfNameMatch + 19, // 61: talos.resource.definitions.network.NfTablesRule.clamp_mss:type_name -> talos.resource.definitions.network.NfTablesClampMSS + 23, // 62: talos.resource.definitions.network.NfTablesRule.match_limit:type_name -> talos.resource.definitions.network.NfTablesLimitMatch + 20, // 63: talos.resource.definitions.network.NfTablesRule.match_conntrack_state:type_name -> talos.resource.definitions.network.NfTablesConntrackStateMatch + 48, // 64: talos.resource.definitions.network.NodeAddressFilterSpec.include_subnets:type_name -> common.NetIPPrefix + 48, // 65: talos.resource.definitions.network.NodeAddressFilterSpec.exclude_subnets:type_name -> common.NetIPPrefix + 48, // 66: talos.resource.definitions.network.NodeAddressSpec.addresses:type_name -> common.NetIPPrefix + 72, // 67: talos.resource.definitions.network.OperatorSpecSpec.operator:type_name -> talos.resource.definitions.enums.NetworkOperator + 7, // 68: talos.resource.definitions.network.OperatorSpecSpec.dhcp4:type_name -> talos.resource.definitions.network.DHCP4OperatorSpec + 8, // 69: talos.resource.definitions.network.OperatorSpecSpec.dhcp6:type_name -> talos.resource.definitions.network.DHCP6OperatorSpec + 44, // 70: talos.resource.definitions.network.OperatorSpecSpec.vip:type_name -> talos.resource.definitions.network.VIPOperatorSpec + 51, // 71: talos.resource.definitions.network.OperatorSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 73, // 72: talos.resource.definitions.network.ProbeSpecSpec.interval:type_name -> google.protobuf.Duration + 39, // 73: talos.resource.definitions.network.ProbeSpecSpec.tcp:type_name -> talos.resource.definitions.network.TCPProbeSpec + 51, // 74: talos.resource.definitions.network.ProbeSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 52, // 75: talos.resource.definitions.network.ResolverSpecSpec.dns_servers:type_name -> common.NetIP + 51, // 76: talos.resource.definitions.network.ResolverSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 52, // 77: talos.resource.definitions.network.ResolverStatusSpec.dns_servers:type_name -> common.NetIP + 49, // 78: talos.resource.definitions.network.RouteSpecSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily + 48, // 79: talos.resource.definitions.network.RouteSpecSpec.destination:type_name -> common.NetIPPrefix + 52, // 80: talos.resource.definitions.network.RouteSpecSpec.source:type_name -> common.NetIP + 52, // 81: talos.resource.definitions.network.RouteSpecSpec.gateway:type_name -> common.NetIP + 74, // 82: talos.resource.definitions.network.RouteSpecSpec.table:type_name -> talos.resource.definitions.enums.NethelpersRoutingTable + 50, // 83: talos.resource.definitions.network.RouteSpecSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope + 75, // 84: talos.resource.definitions.network.RouteSpecSpec.type:type_name -> talos.resource.definitions.enums.NethelpersRouteType + 76, // 85: talos.resource.definitions.network.RouteSpecSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersRouteProtocol + 51, // 86: talos.resource.definitions.network.RouteSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 49, // 87: talos.resource.definitions.network.RouteStatusSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily + 48, // 88: talos.resource.definitions.network.RouteStatusSpec.destination:type_name -> common.NetIPPrefix + 52, // 89: talos.resource.definitions.network.RouteStatusSpec.source:type_name -> common.NetIP + 52, // 90: talos.resource.definitions.network.RouteStatusSpec.gateway:type_name -> common.NetIP + 74, // 91: talos.resource.definitions.network.RouteStatusSpec.table:type_name -> talos.resource.definitions.enums.NethelpersRoutingTable + 50, // 92: talos.resource.definitions.network.RouteStatusSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope + 75, // 93: talos.resource.definitions.network.RouteStatusSpec.type:type_name -> talos.resource.definitions.enums.NethelpersRouteType + 76, // 94: talos.resource.definitions.network.RouteStatusSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersRouteProtocol + 73, // 95: talos.resource.definitions.network.TCPProbeSpec.timeout:type_name -> google.protobuf.Duration + 51, // 96: talos.resource.definitions.network.TimeServerSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 52, // 97: talos.resource.definitions.network.VIPOperatorSpec.ip:type_name -> common.NetIP + 42, // 98: talos.resource.definitions.network.VIPOperatorSpec.equinix_metal:type_name -> talos.resource.definitions.network.VIPEquinixMetalSpec + 43, // 99: talos.resource.definitions.network.VIPOperatorSpec.h_cloud:type_name -> talos.resource.definitions.network.VIPHCloudSpec + 77, // 100: talos.resource.definitions.network.VLANSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersVLANProtocol + 73, // 101: talos.resource.definitions.network.WireguardPeer.persistent_keepalive_interval:type_name -> google.protobuf.Duration + 48, // 102: talos.resource.definitions.network.WireguardPeer.allowed_ips:type_name -> common.NetIPPrefix + 46, // 103: talos.resource.definitions.network.WireguardSpec.peers:type_name -> talos.resource.definitions.network.WireguardPeer + 104, // [104:104] is the sub-list for method output_type + 104, // [104:104] is the sub-list for method input_type + 104, // [104:104] is the sub-list for extension type_name + 104, // [104:104] is the sub-list for extension extendee + 0, // [0:104] is the sub-list for field type_name } func init() { file_resource_definitions_network_network_proto_init() } diff --git a/pkg/machinery/api/resource/definitions/network/network_vtproto.pb.go b/pkg/machinery/api/resource/definitions/network/network_vtproto.pb.go index 9ba36962afe..4881bb4e956 100644 --- a/pkg/machinery/api/resource/definitions/network/network_vtproto.pb.go +++ b/pkg/machinery/api/resource/definitions/network/network_vtproto.pb.go @@ -870,6 +870,28 @@ func (m *HostDNSConfigSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.ServiceHostDnsAddressV6 != nil { + if vtmsg, ok := interface{}(m.ServiceHostDnsAddressV6).(interface { + MarshalToSizedBufferVT([]byte) (int, error) + }); ok { + size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + } else { + encoded, err := proto.Marshal(m.ServiceHostDnsAddressV6) + if err != nil { + return 0, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(encoded))) + } + i-- + dAtA[i] = 0x2a + } if m.ResolveMemberNames { i-- if m.ResolveMemberNames { @@ -3941,6 +3963,16 @@ func (m *HostDNSConfigSpec) SizeVT() (n int) { if m.ResolveMemberNames { n += 2 } + if m.ServiceHostDnsAddressV6 != nil { + if size, ok := interface{}(m.ServiceHostDnsAddressV6).(interface { + SizeVT() int + }); ok { + l = size.SizeVT() + } else { + l = proto.Size(m.ServiceHostDnsAddressV6) + } + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } @@ -7010,6 +7042,50 @@ func (m *HostDNSConfigSpec) UnmarshalVT(dAtA []byte) error { } } m.ResolveMemberNames = bool(v != 0) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ServiceHostDnsAddressV6", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ServiceHostDnsAddressV6 == nil { + m.ServiceHostDnsAddressV6 = &common.NetIP{} + } + if unmarshal, ok := interface{}(m.ServiceHostDnsAddressV6).(interface { + UnmarshalVT([]byte) error + }); ok { + if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + } else { + if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.ServiceHostDnsAddressV6); err != nil { + return err + } + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/pkg/machinery/constants/constants.go b/pkg/machinery/constants/constants.go index 87f55a724a1..dbe7123f652 100644 --- a/pkg/machinery/constants/constants.go +++ b/pkg/machinery/constants/constants.go @@ -1176,6 +1176,11 @@ const ( // Note: 116 = 't' and 108 = 'l' in ASCII. HostDNSAddress = "169.254.116.108" + // HostDNSAddressV6 is the address of the host DNS server in IPv6 network. + // + // Note: fd54:616c:6f73::204f:5320:444e:53 is "Talos OS DNS". + HostDNSAddressV6 = "fd54:616c:6f73::204f:5320:444e:531" + // MetalAgentModeFlagPath is the path to the file indicating if the node is running in Metal Agent mode. MetalAgentModeFlagPath = "/usr/local/etc/is-metal-agent" ) diff --git a/pkg/machinery/resources/network/hostdns_config.go b/pkg/machinery/resources/network/hostdns_config.go index b59f4164015..41425622aa1 100644 --- a/pkg/machinery/resources/network/hostdns_config.go +++ b/pkg/machinery/resources/network/hostdns_config.go @@ -28,10 +28,11 @@ const HostDNSConfigID resource.ID = "config" // //gotagsrewrite:gen type HostDNSConfigSpec struct { - Enabled bool `yaml:"enabled" protobuf:"1"` - ListenAddresses []netip.AddrPort `yaml:"listenAddresses,omitempty" protobuf:"2"` - ServiceHostDNSAddress netip.Addr `yaml:"serviceHostDNSAddress,omitempty" protobuf:"3"` - ResolveMemberNames bool `yaml:"resolveMemberNames,omitempty" protobuf:"4"` + Enabled bool `yaml:"enabled" protobuf:"1"` + ListenAddresses []netip.AddrPort `yaml:"listenAddresses,omitempty" protobuf:"2"` + ServiceHostDNSAddress netip.Addr `yaml:"serviceHostDNSAddress,omitempty" protobuf:"3"` + ResolveMemberNames bool `yaml:"resolveMemberNames,omitempty" protobuf:"4"` + ServiceHostDNSAddressV6 netip.Addr `yaml:"serviceHostDNSAddressV6,omitempty" protobuf:"5"` } // NewHostDNSConfig initializes a HostDNSConfig resource. diff --git a/website/content/v1.9/reference/api.md b/website/content/v1.9/reference/api.md index 7e04d3eae18..8d9503cf5f0 100644 --- a/website/content/v1.9/reference/api.md +++ b/website/content/v1.9/reference/api.md @@ -3471,6 +3471,7 @@ HostDNSConfigSpec describes host DNS config. | listen_addresses | [common.NetIPPort](#common.NetIPPort) | repeated | | | service_host_dns_address | [common.NetIP](#common.NetIP) | | | | resolve_member_names | [bool](#bool) | | | +| service_host_dns_address_v6 | [common.NetIP](#common.NetIP) | | |