diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index cdc3b487d..858dec41a 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -15,3 +15,4 @@ jobs: uses: codespell-project/actions-codespell@v2 with: ignore_words_list: allos,ans,dne,noe,referr,ssudo,te,tranfer,ue + skip: go.*,zititest/go.* diff --git a/CHANGELOG.md b/CHANGELOG.md index dc983e6cf..6a1da4145 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## What's New * Auth Rate Limiter +* Link Management Fixes * ziti edge quickstart command deprecates redundant --already-initialized flag. The identical behavior is implied by --home. ## Backwards compatibility @@ -11,6 +12,9 @@ This release includes new response types from the REST authentication APIS. They `429` (server too busy) responses to auth requests. As this is an API change, the version number is being bumped to 0.32. +If controller and router are both v0.32 or later, only the router which dialed a link will report it to the controller. +If the controller is older, newer routers will report links from both the dialing and listening side of the link. + ## Auth Rate Limiter In order to prevent clients from overwhelming the server with auth requests, an auth rate limiter has been introduced. @@ -37,15 +41,46 @@ New metrics: * `auth.limiter.window_size` - current size at which new auth attempts will be rejected * `auth.limiter.work_timer` - tracks the rate at which api sessions are being created and how long it's taking to create them +## Link Management Fixes + +With long lived link ids, there was potential for link control message to be ambiguous, as the link id wasn't enough to identify +a specific iteration of that link. An iteration field has been added to links so that messaging is unambiguous. +Links will also only be reported from the dialing router now to reduce ambiguouity and race condition in link control channel +messaging. + +## Router SSL Handshake Timeout Config + +There is a new router config setting which allows setting the SSL handshake timeout for TLS connections, when using ALPN for listeners. + +``` +tls: + handshakeTimeout: 15s +``` + ## Component Updates and Bug Fixes -* github.com/openziti/channel/v2: [v2.0.111 -> v2.0.113](https://github.com/openziti/channel/compare/v2.0.111...v2.0.113) +* github.com/openziti/channel/v2: [v2.0.111 -> v2.0.116](https://github.com/openziti/channel/compare/v2.0.111...v2.0.116) + * [Issue #123](https://github.com/openziti/channel/issues/123) - Ensure hello messages respect connect timeout * [Issue #120](https://github.com/openziti/channel/issues/120) - Allow handling new underlay instances with function instead of channel -* github.com/openziti/edge-api: [v0.26.6 -> v0.26.7](https://github.com/openziti/edge-api/compare/v0.26.6...v0.26.7) -* github.com/openziti/sdk-golang: [v0.22.0 -> v0.22.6](https://github.com/openziti/sdk-golang/compare/v0.22.0...v0.22.6) -* github.com/openziti/secretstream: [v0.1.14 -> v0.1.15](https://github.com/openziti/secretstream/compare/v0.1.14...v0.1.15) +* github.com/openziti/edge-api: [v0.26.6 -> v0.26.8](https://github.com/openziti/edge-api/compare/v0.26.6...v0.26.8) +* github.com/openziti/foundation/v2: [v2.0.35 -> v2.0.36](https://github.com/openziti/foundation/compare/v2.0.35...v2.0.36) + * [Issue #391](https://github.com/openziti/foundation/issues/391) - goroutine pool can stall if configured for 0 min workers and with single producer + +* github.com/openziti/identity: [v1.0.68 -> v1.0.69](https://github.com/openziti/identity/compare/v1.0.68...v1.0.69) +* github.com/openziti/metrics: [v1.2.41 -> v1.2.43](https://github.com/openziti/metrics/compare/v1.2.41...v1.2.43) +* github.com/openziti/runzmd: [v1.0.36 -> v1.0.37](https://github.com/openziti/runzmd/compare/v1.0.36...v1.0.37) +* github.com/openziti/sdk-golang: [v0.22.0 -> v0.22.17](https://github.com/openziti/sdk-golang/compare/v0.22.0...v0.22.17) + * [Issue #482](https://github.com/openziti/sdk-golang/issues/482) - Deprecate ListenOptions.MaxConnections in favor of MaxTerminators + +* github.com/openziti/secretstream: [v0.1.14 -> v0.1.16](https://github.com/openziti/secretstream/compare/v0.1.14...v0.1.16) +* github.com/openziti/storage: [v0.2.27 -> v0.2.28](https://github.com/openziti/storage/compare/v0.2.27...v0.2.28) +* github.com/openziti/transport/v2: [v2.0.119 -> v2.0.121](https://github.com/openziti/transport/compare/v2.0.119...v2.0.121) + * [Issue #73](https://github.com/openziti/transport/issues/73) - Allow overriding shared TLS/ALPN listener SSL handshake timeout + * github.com/openziti/ziti: [v0.31.4 -> v0.32.0](https://github.com/openziti/ziti/compare/v0.31.4...v0.32.0) + * [Issue #1692](https://github.com/openziti/ziti/issues/1692) - Improve link stability with long lived link ids + * [Issue #1693](https://github.com/openziti/ziti/issues/1693) - Make links owned by the dialing router * [Issue #1685](https://github.com/openziti/ziti/issues/1685) - Race condition where we try to create terminator after client connection is closed * [Issue #1678](https://github.com/openziti/ziti/issues/1678) - Add link validation utility * [Issue #1673](https://github.com/openziti/ziti/issues/1673) - xgress dialers not getting passed xgress config diff --git a/common/capabilities/check.go b/common/capabilities/check.go new file mode 100644 index 000000000..6e7373419 --- /dev/null +++ b/common/capabilities/check.go @@ -0,0 +1,33 @@ +/* + Copyright NetFoundry Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package capabilities + +import ( + "github.com/openziti/channel/v2" + "github.com/openziti/ziti/common/pb/ctrl_pb" + "math/big" +) + +func IsCapable(ch channel.Channel, capability int) bool { + headers := ch.Underlay().Headers() + if val, found := headers[int32(ctrl_pb.ControlHeaders_CapabilitiesHeader)]; found { + capabilitiesMask := &big.Int{} + capabilitiesMask.SetBytes(val) + return capabilitiesMask.Bit(capability) == 1 + } + return false +} diff --git a/common/capabilities/consts.go b/common/capabilities/consts.go index 0a73ae725..ad29acf53 100644 --- a/common/capabilities/consts.go +++ b/common/capabilities/consts.go @@ -17,5 +17,6 @@ package capabilities const ( - ControllerCreateTerminatorV2 int = 1 + ControllerCreateTerminatorV2 int = 1 + ControllerSingleRouterLinkSource int = 2 ) diff --git a/common/inspect/links_inspect_result.go b/common/inspect/links_inspect_result.go index c1c2807f0..4b00388c1 100644 --- a/common/inspect/links_inspect_result.go +++ b/common/inspect/links_inspect_result.go @@ -28,6 +28,7 @@ type LinksInspectResult struct { type LinkInspectDetail struct { Id string `json:"id"` + Iteration uint32 `json:"iteration"` Key string `json:"key"` Split bool `json:"split"` Protocol string `json:"protocol"` @@ -49,8 +50,8 @@ type LinkState struct { Id string `json:"id"` Key string `json:"key"` Status string `json:"status"` - DialAttempts uint `json:"dialAttempts"` - ConnectedCount uint `json:"connectedCount"` + DialAttempts uint64 `json:"dialAttempts"` + ConnectedCount uint64 `json:"connectedCount"` RetryDelay string `json:"retryDelay"` NextDial string `json:"nextDial"` TargetAddress string `json:"targetAddress"` @@ -58,4 +59,5 @@ type LinkState struct { TargetBinding string `json:"targetBinding"` DialerGroups []string `json:"dialerGroups"` DialerBinding string `json:"dialerBinding"` + CtrlsNotified bool `json:"ctrlsNotified"` } diff --git a/common/pb/ctrl_pb/ctrl.pb.go b/common/pb/ctrl_pb/ctrl.pb.go index 7edd57df1..16e4e1a94 100644 --- a/common/pb/ctrl_pb/ctrl.pb.go +++ b/common/pb/ctrl_pb/ctrl.pb.go @@ -57,9 +57,6 @@ const ( ContentType_ValidateTerminatorsV2ResponseType ContentType = 1042 ContentType_DecommissionRouterRequestType ContentType = 1043 ContentType_PeerStateChangeRequestType ContentType = 1050 - ContentType_ListenersHeader ContentType = 10 - ContentType_RouterMetadataHeader ContentType = 11 - ContentType_CapabilitiesHeader ContentType = 12 ) // Enum value maps for ContentType. @@ -93,9 +90,6 @@ var ( 1042: "ValidateTerminatorsV2ResponseType", 1043: "DecommissionRouterRequestType", 1050: "PeerStateChangeRequestType", - 10: "ListenersHeader", - 11: "RouterMetadataHeader", - 12: "CapabilitiesHeader", } ContentType_value = map[string]int32{ "Zero": 0, @@ -126,9 +120,6 @@ var ( "ValidateTerminatorsV2ResponseType": 1042, "DecommissionRouterRequestType": 1043, "PeerStateChangeRequestType": 1050, - "ListenersHeader": 10, - "RouterMetadataHeader": 11, - "CapabilitiesHeader": 12, } ) @@ -159,6 +150,58 @@ func (ContentType) EnumDescriptor() ([]byte, []int) { return file_ctrl_proto_rawDescGZIP(), []int{0} } +type ControlHeaders int32 + +const ( + ControlHeaders_NoneHeader ControlHeaders = 0 + ControlHeaders_ListenersHeader ControlHeaders = 10 + ControlHeaders_RouterMetadataHeader ControlHeaders = 11 + ControlHeaders_CapabilitiesHeader ControlHeaders = 12 +) + +// Enum value maps for ControlHeaders. +var ( + ControlHeaders_name = map[int32]string{ + 0: "NoneHeader", + 10: "ListenersHeader", + 11: "RouterMetadataHeader", + 12: "CapabilitiesHeader", + } + ControlHeaders_value = map[string]int32{ + "NoneHeader": 0, + "ListenersHeader": 10, + "RouterMetadataHeader": 11, + "CapabilitiesHeader": 12, + } +) + +func (x ControlHeaders) Enum() *ControlHeaders { + p := new(ControlHeaders) + *p = x + return p +} + +func (x ControlHeaders) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ControlHeaders) Descriptor() protoreflect.EnumDescriptor { + return file_ctrl_proto_enumTypes[1].Descriptor() +} + +func (ControlHeaders) Type() protoreflect.EnumType { + return &file_ctrl_proto_enumTypes[1] +} + +func (x ControlHeaders) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ControlHeaders.Descriptor instead. +func (ControlHeaders) EnumDescriptor() ([]byte, []int) { + return file_ctrl_proto_rawDescGZIP(), []int{1} +} + type RouterCapability int32 const ( @@ -189,11 +232,11 @@ func (x RouterCapability) String() string { } func (RouterCapability) Descriptor() protoreflect.EnumDescriptor { - return file_ctrl_proto_enumTypes[1].Descriptor() + return file_ctrl_proto_enumTypes[2].Descriptor() } func (RouterCapability) Type() protoreflect.EnumType { - return &file_ctrl_proto_enumTypes[1] + return &file_ctrl_proto_enumTypes[2] } func (x RouterCapability) Number() protoreflect.EnumNumber { @@ -202,7 +245,7 @@ func (x RouterCapability) Number() protoreflect.EnumNumber { // Deprecated: Use RouterCapability.Descriptor instead. func (RouterCapability) EnumDescriptor() ([]byte, []int) { - return file_ctrl_proto_rawDescGZIP(), []int{1} + return file_ctrl_proto_rawDescGZIP(), []int{2} } // SettingTypes are used with the Settings message send arbitrary settings to routers. @@ -239,11 +282,11 @@ func (x SettingTypes) String() string { } func (SettingTypes) Descriptor() protoreflect.EnumDescriptor { - return file_ctrl_proto_enumTypes[2].Descriptor() + return file_ctrl_proto_enumTypes[3].Descriptor() } func (SettingTypes) Type() protoreflect.EnumType { - return &file_ctrl_proto_enumTypes[2] + return &file_ctrl_proto_enumTypes[3] } func (x SettingTypes) Number() protoreflect.EnumNumber { @@ -252,7 +295,7 @@ func (x SettingTypes) Number() protoreflect.EnumNumber { // Deprecated: Use SettingTypes.Descriptor instead. func (SettingTypes) EnumDescriptor() ([]byte, []int) { - return file_ctrl_proto_rawDescGZIP(), []int{2} + return file_ctrl_proto_rawDescGZIP(), []int{3} } type TerminatorPrecedence int32 @@ -288,11 +331,11 @@ func (x TerminatorPrecedence) String() string { } func (TerminatorPrecedence) Descriptor() protoreflect.EnumDescriptor { - return file_ctrl_proto_enumTypes[3].Descriptor() + return file_ctrl_proto_enumTypes[4].Descriptor() } func (TerminatorPrecedence) Type() protoreflect.EnumType { - return &file_ctrl_proto_enumTypes[3] + return &file_ctrl_proto_enumTypes[4] } func (x TerminatorPrecedence) Number() protoreflect.EnumNumber { @@ -301,7 +344,7 @@ func (x TerminatorPrecedence) Number() protoreflect.EnumNumber { // Deprecated: Use TerminatorPrecedence.Descriptor instead. func (TerminatorPrecedence) EnumDescriptor() ([]byte, []int) { - return file_ctrl_proto_rawDescGZIP(), []int{3} + return file_ctrl_proto_rawDescGZIP(), []int{4} } type TerminatorInvalidReason int32 @@ -337,11 +380,11 @@ func (x TerminatorInvalidReason) String() string { } func (TerminatorInvalidReason) Descriptor() protoreflect.EnumDescriptor { - return file_ctrl_proto_enumTypes[4].Descriptor() + return file_ctrl_proto_enumTypes[5].Descriptor() } func (TerminatorInvalidReason) Type() protoreflect.EnumType { - return &file_ctrl_proto_enumTypes[4] + return &file_ctrl_proto_enumTypes[5] } func (x TerminatorInvalidReason) Number() protoreflect.EnumNumber { @@ -350,7 +393,7 @@ func (x TerminatorInvalidReason) Number() protoreflect.EnumNumber { // Deprecated: Use TerminatorInvalidReason.Descriptor instead. func (TerminatorInvalidReason) EnumDescriptor() ([]byte, []int) { - return file_ctrl_proto_rawDescGZIP(), []int{4} + return file_ctrl_proto_rawDescGZIP(), []int{5} } type FaultSubject int32 @@ -395,11 +438,11 @@ func (x FaultSubject) String() string { } func (FaultSubject) Descriptor() protoreflect.EnumDescriptor { - return file_ctrl_proto_enumTypes[5].Descriptor() + return file_ctrl_proto_enumTypes[6].Descriptor() } func (FaultSubject) Type() protoreflect.EnumType { - return &file_ctrl_proto_enumTypes[5] + return &file_ctrl_proto_enumTypes[6] } func (x FaultSubject) Number() protoreflect.EnumNumber { @@ -408,7 +451,7 @@ func (x FaultSubject) Number() protoreflect.EnumNumber { // Deprecated: Use FaultSubject.Descriptor instead. func (FaultSubject) EnumDescriptor() ([]byte, []int) { - return file_ctrl_proto_rawDescGZIP(), []int{5} + return file_ctrl_proto_rawDescGZIP(), []int{6} } type DestType int32 @@ -444,11 +487,11 @@ func (x DestType) String() string { } func (DestType) Descriptor() protoreflect.EnumDescriptor { - return file_ctrl_proto_enumTypes[6].Descriptor() + return file_ctrl_proto_enumTypes[7].Descriptor() } func (DestType) Type() protoreflect.EnumType { - return &file_ctrl_proto_enumTypes[6] + return &file_ctrl_proto_enumTypes[7] } func (x DestType) Number() protoreflect.EnumNumber { @@ -457,7 +500,7 @@ func (x DestType) Number() protoreflect.EnumNumber { // Deprecated: Use DestType.Descriptor instead. func (DestType) EnumDescriptor() ([]byte, []int) { - return file_ctrl_proto_rawDescGZIP(), []int{6} + return file_ctrl_proto_rawDescGZIP(), []int{7} } type PeerState int32 @@ -493,11 +536,11 @@ func (x PeerState) String() string { } func (PeerState) Descriptor() protoreflect.EnumDescriptor { - return file_ctrl_proto_enumTypes[7].Descriptor() + return file_ctrl_proto_enumTypes[8].Descriptor() } func (PeerState) Type() protoreflect.EnumType { - return &file_ctrl_proto_enumTypes[7] + return &file_ctrl_proto_enumTypes[8] } func (x PeerState) Number() protoreflect.EnumNumber { @@ -506,7 +549,7 @@ func (x PeerState) Number() protoreflect.EnumNumber { // Deprecated: Use PeerState.Descriptor instead. func (PeerState) EnumDescriptor() ([]byte, []int) { - return file_ctrl_proto_rawDescGZIP(), []int{7} + return file_ctrl_proto_rawDescGZIP(), []int{8} } // Settings are sent to to routers to configure arbitrary runtime settings. @@ -1475,8 +1518,9 @@ type Fault struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Subject FaultSubject `protobuf:"varint,1,opt,name=subject,proto3,enum=ziti.ctrl.pb.FaultSubject" json:"subject,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + Subject FaultSubject `protobuf:"varint,1,opt,name=subject,proto3,enum=ziti.ctrl.pb.FaultSubject" json:"subject,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + Iteration uint32 `protobuf:"varint,3,opt,name=iteration,proto3" json:"iteration,omitempty"` } func (x *Fault) Reset() { @@ -1525,6 +1569,13 @@ func (x *Fault) GetId() string { return "" } +func (x *Fault) GetIteration() uint32 { + if x != nil { + return x.Iteration + } + return 0 +} + type Context struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2259,6 +2310,7 @@ type RouterLinks_RouterLink struct { LinkProtocol string `protobuf:"bytes,3,opt,name=linkProtocol,proto3" json:"linkProtocol,omitempty"` LinkCostTags []string `protobuf:"bytes,4,rep,name=linkCostTags,proto3" json:"linkCostTags,omitempty"` DialAddress string `protobuf:"bytes,5,opt,name=dialAddress,proto3" json:"dialAddress,omitempty"` + Iteration uint32 `protobuf:"varint,6,opt,name=iteration,proto3" json:"iteration,omitempty"` } func (x *RouterLinks_RouterLink) Reset() { @@ -2328,6 +2380,13 @@ func (x *RouterLinks_RouterLink) GetDialAddress() string { return "" } +func (x *RouterLinks_RouterLink) GetIteration() uint32 { + if x != nil { + return x.Iteration + } + return 0 +} + type Route_Egress struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2663,12 +2722,12 @@ var file_ctrl_proto_rawDesc = []byte{ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x05, 0x63, 0x6f, 0x6e, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x6e, - 0x6e, 0x52, 0x05, 0x63, 0x6f, 0x6e, 0x6e, 0x73, 0x22, 0xf6, 0x01, 0x0a, 0x0b, 0x52, 0x6f, 0x75, + 0x6e, 0x52, 0x05, 0x63, 0x6f, 0x6e, 0x6e, 0x73, 0x22, 0x94, 0x02, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x3a, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x05, 0x6c, - 0x69, 0x6e, 0x6b, 0x73, 0x1a, 0xaa, 0x01, 0x0a, 0x0a, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, + 0x69, 0x6e, 0x6b, 0x73, 0x1a, 0xc8, 0x01, 0x0a, 0x0a, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x52, @@ -2679,218 +2738,224 @@ var file_ctrl_proto_rawDesc = []byte{ 0x09, 0x52, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x73, 0x74, 0x54, 0x61, 0x67, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x22, 0x4d, 0x0a, 0x05, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x34, 0x0a, 0x07, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x7a, 0x69, - 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x61, 0x75, 0x6c, 0x74, - 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, - 0x22, 0xa1, 0x01, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x39, 0x0a, 0x06, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x7a, - 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, - 0x65, 0x6c, 0x4d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x68, - 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4d, 0x61, 0x73, 0x6b, 0x1a, 0x39, 0x0a, 0x0b, 0x46, 0x69, 0x65, - 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc4, 0x05, 0x0a, 0x05, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1c, - 0x0a, 0x09, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, - 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x61, - 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x12, 0x32, 0x0a, 0x06, 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, - 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x45, 0x67, 0x72, 0x65, - 0x73, 0x73, 0x52, 0x06, 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x6f, - 0x72, 0x77, 0x61, 0x72, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x7a, - 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x2e, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x52, 0x08, 0x66, 0x6f, 0x72, 0x77, 0x61, - 0x72, 0x64, 0x73, 0x12, 0x2f, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, - 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x78, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x31, - 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x7a, - 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x74, 0x61, 0x67, - 0x73, 0x1a, 0xe1, 0x01, 0x0a, 0x06, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, - 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, - 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x08, 0x70, 0x65, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, - 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, - 0x2e, 0x50, 0x65, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, - 0x70, 0x65, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x50, 0x65, 0x65, 0x72, - 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x7b, 0x0a, 0x07, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, - 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x30, 0x0a, 0x07, 0x64, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x16, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, - 0x2e, 0x44, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x64, 0x73, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x39, 0x0a, 0x07, 0x55, - 0x6e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, - 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x69, 0x72, 0x63, 0x75, - 0x69, 0x74, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6e, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x03, 0x6e, 0x6f, 0x77, 0x22, 0x3a, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x73, 0x22, 0xc1, 0x01, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, 0x16, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x42, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, - 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x1a, 0x38, 0x0a, 0x0c, - 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x4e, 0x0a, 0x0c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, - 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, - 0x70, 0x72, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x98, 0x01, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x65, - 0x6e, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, - 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x73, - 0x74, 0x54, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x73, - 0x74, 0x54, 0x61, 0x67, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x22, 0x0a, - 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x22, 0x41, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x34, - 0x0a, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x16, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x65, - 0x6e, 0x65, 0x72, 0x73, 0x22, 0x65, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x74, - 0x72, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, - 0x1a, 0x0a, 0x08, 0x69, 0x73, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x08, 0x69, 0x73, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0xa0, 0x01, 0x0a, 0x0f, - 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, - 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x34, 0x0a, 0x09, 0x6c, 0x69, 0x73, 0x74, - 0x65, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x7a, 0x69, - 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, - 0x6e, 0x65, 0x72, 0x52, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x22, 0x4b, - 0x0a, 0x10, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x73, 0x12, 0x37, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, - 0x70, 0x62, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x54, 0x0a, 0x0e, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x42, 0x0a, - 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, - 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, - 0x69, 0x74, 0x79, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, - 0x73, 0x2a, 0xca, 0x06, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x65, 0x72, 0x6f, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x12, 0x43, - 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x10, 0xe8, 0x07, 0x12, 0x0d, 0x0a, 0x08, 0x44, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, - 0x10, 0xea, 0x07, 0x12, 0x16, 0x0a, 0x11, 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x10, 0xeb, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x46, - 0x61, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xec, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xed, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x55, - 0x6e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xee, 0x07, 0x12, 0x10, 0x0a, - 0x0b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x54, 0x79, 0x70, 0x65, 0x10, 0xef, 0x07, 0x12, - 0x20, 0x0a, 0x1b, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x50, 0x69, 0x70, 0x65, 0x54, 0x72, 0x61, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf0, - 0x07, 0x12, 0x13, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x10, 0xf2, 0x07, 0x12, 0x20, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf3, 0x07, 0x12, 0x20, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf4, 0x07, 0x12, 0x17, 0x0a, 0x12, 0x49, 0x6e, - 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x10, 0xf5, 0x07, 0x12, 0x18, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf6, 0x07, 0x12, 0x23, 0x0a, - 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, - 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, - 0xf9, 0x07, 0x12, 0x20, 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, + 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x6b, 0x0a, 0x05, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x34, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x7a, 0x69, 0x74, 0x69, + 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x53, 0x75, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1c, + 0x0a, 0x09, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x09, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa1, 0x01, 0x0a, + 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, + 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4d, 0x61, + 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, + 0x6c, 0x4d, 0x61, 0x73, 0x6b, 0x1a, 0x39, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0xc4, 0x05, 0x0a, 0x05, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x69, + 0x72, 0x63, 0x75, 0x69, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, + 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x74, 0x74, 0x65, + 0x6d, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x61, 0x74, 0x74, 0x65, 0x6d, + 0x70, 0x74, 0x12, 0x32, 0x0a, 0x06, 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, + 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x06, + 0x65, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, + 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, + 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x46, 0x6f, + 0x72, 0x77, 0x61, 0x72, 0x64, 0x52, 0x08, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x73, 0x12, + 0x2f, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x31, 0x0a, 0x04, 0x74, 0x61, + 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, + 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x54, 0x61, + 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x1a, 0xe1, 0x01, + 0x0a, 0x06, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x69, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x69, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x20, 0x0a, 0x0b, + 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, + 0x0a, 0x08, 0x70, 0x65, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x28, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x65, 0x65, + 0x72, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x70, 0x65, 0x65, 0x72, + 0x44, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x50, 0x65, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x1a, 0x7b, 0x0a, 0x07, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x1e, 0x0a, 0x0a, + 0x73, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x73, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1e, 0x0a, 0x0a, + 0x64, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x64, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x30, 0x0a, 0x07, + 0x64, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, + 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x73, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x64, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x37, + 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x39, 0x0a, 0x07, 0x55, 0x6e, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x49, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x49, 0x64, + 0x12, 0x10, 0x0a, 0x03, 0x6e, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x6e, + 0x6f, 0x77, 0x22, 0x3a, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, + 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0xc1, + 0x01, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 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, 0x16, 0x0a, 0x06, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x73, 0x12, 0x42, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, + 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x1a, 0x38, 0x0a, 0x0c, 0x49, 0x6e, 0x73, 0x70, + 0x65, 0x63, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x22, 0x4e, 0x0a, 0x0c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x22, + 0x0a, 0x0c, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x73, 0x22, 0x98, 0x01, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, + 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x73, 0x74, 0x54, 0x61, 0x67, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x73, 0x74, 0x54, 0x61, 0x67, + 0x73, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x22, 0x41, 0x0a, + 0x09, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x34, 0x0a, 0x09, 0x6c, 0x69, + 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, + 0x22, 0x65, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x74, 0x72, 0x6c, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1a, 0x0a, 0x08, 0x69, + 0x73, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, + 0x73, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0xa0, 0x01, 0x0a, 0x0f, 0x50, 0x65, 0x65, 0x72, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, + 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x34, 0x0a, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, + 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, + 0x09, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x22, 0x4b, 0x0a, 0x10, 0x50, 0x65, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x37, + 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1d, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x50, + 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x07, + 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x54, 0x0a, 0x0e, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x42, 0x0a, 0x0c, 0x63, 0x61, 0x70, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, + 0x1e, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x52, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, + 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2a, 0x83, 0x06, + 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, + 0x04, 0x5a, 0x65, 0x72, 0x6f, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x12, 0x43, 0x69, 0x72, 0x63, 0x75, + 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe8, 0x07, + 0x12, 0x0d, 0x0a, 0x08, 0x44, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x10, 0xea, 0x07, 0x12, + 0x16, 0x0a, 0x11, 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x54, 0x79, 0x70, 0x65, 0x10, 0xeb, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x46, 0x61, 0x75, 0x6c, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x10, 0xec, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x10, 0xed, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x55, 0x6e, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xee, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x54, 0x79, 0x70, 0x65, 0x10, 0xef, 0x07, 0x12, 0x20, 0x0a, 0x1b, 0x54, + 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x50, 0x69, 0x70, 0x65, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf0, 0x07, 0x12, 0x13, 0x0a, + 0x0e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, + 0xf2, 0x07, 0x12, 0x20, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x10, 0xfa, 0x07, 0x12, 0x11, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, - 0x54, 0x79, 0x70, 0x65, 0x10, 0xfc, 0x07, 0x12, 0x1c, 0x0a, 0x17, 0x43, 0x69, 0x72, 0x63, 0x75, - 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, - 0x70, 0x65, 0x10, 0x8a, 0x08, 0x12, 0x14, 0x0a, 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, - 0x69, 0x6e, 0x6b, 0x73, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8b, 0x08, 0x12, 0x15, 0x0a, 0x10, 0x56, - 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x10, - 0x8c, 0x08, 0x12, 0x1c, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x74, 0x72, 0x6c, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8d, 0x08, - 0x12, 0x21, 0x0a, 0x1c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, - 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x10, 0x8e, 0x08, 0x12, 0x1d, 0x0a, 0x18, 0x51, 0x75, 0x69, 0x65, 0x73, 0x63, 0x65, 0x52, 0x6f, + 0x65, 0x10, 0xf3, 0x07, 0x12, 0x20, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, + 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x10, 0xf4, 0x07, 0x12, 0x17, 0x0a, 0x12, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf5, 0x07, 0x12, + 0x18, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf6, 0x07, 0x12, 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf9, 0x07, 0x12, 0x20, + 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfa, 0x07, + 0x12, 0x11, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x54, 0x79, 0x70, 0x65, + 0x10, 0xfc, 0x07, 0x12, 0x1c, 0x0a, 0x17, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8a, + 0x08, 0x12, 0x14, 0x0a, 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, + 0x54, 0x79, 0x70, 0x65, 0x10, 0x8b, 0x08, 0x12, 0x15, 0x0a, 0x10, 0x56, 0x65, 0x72, 0x69, 0x66, + 0x79, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8c, 0x08, 0x12, 0x1c, + 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x74, 0x72, 0x6c, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8d, 0x08, 0x12, 0x21, 0x0a, 0x1c, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8e, 0x08, 0x12, + 0x1d, 0x0a, 0x18, 0x51, 0x75, 0x69, 0x65, 0x73, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8f, 0x08, 0x12, 0x1f, + 0x0a, 0x1a, 0x44, 0x65, 0x71, 0x75, 0x69, 0x65, 0x73, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x90, 0x08, 0x12, + 0x25, 0x0a, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x10, 0x91, 0x08, 0x12, 0x26, 0x0a, 0x21, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x56, 0x32, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0x92, 0x08, 0x12, 0x22, + 0x0a, 0x1d, 0x44, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, - 0x8f, 0x08, 0x12, 0x1f, 0x0a, 0x1a, 0x44, 0x65, 0x71, 0x75, 0x69, 0x65, 0x73, 0x63, 0x65, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x10, 0x90, 0x08, 0x12, 0x25, 0x0a, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, - 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x91, 0x08, 0x12, 0x26, 0x0a, 0x21, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, - 0x73, 0x56, 0x32, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, - 0x92, 0x08, 0x12, 0x22, 0x0a, 0x1d, 0x44, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x10, 0x93, 0x08, 0x12, 0x1f, 0x0a, 0x1a, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x10, 0x9a, 0x08, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x65, - 0x6e, 0x65, 0x72, 0x73, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x0a, 0x12, 0x18, 0x0a, 0x14, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x48, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x10, 0x0b, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x0c, 0x2a, 0x3a, - 0x0a, 0x10, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, - 0x74, 0x79, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, - 0x5a, 0x65, 0x72, 0x6f, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x10, 0x01, 0x2a, 0x35, 0x0a, 0x0c, 0x53, 0x65, - 0x74, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x6e, - 0x75, 0x73, 0x65, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x12, 0x0a, - 0x0e, 0x4e, 0x65, 0x77, 0x43, 0x74, 0x72, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, - 0x01, 0x2a, 0x3d, 0x0a, 0x14, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x50, - 0x72, 0x65, 0x63, 0x65, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x65, 0x66, - 0x61, 0x75, 0x6c, 0x74, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x64, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x02, - 0x2a, 0x52, 0x0a, 0x17, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x0e, 0x55, - 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, - 0x15, 0x0a, 0x11, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, - 0x61, 0x74, 0x6f, 0x72, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x61, 0x64, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x10, 0x02, 0x2a, 0x83, 0x01, 0x0a, 0x0c, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x53, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, - 0x46, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x67, 0x72, 0x65, 0x73, - 0x73, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x69, 0x6e, 0x6b, - 0x46, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x46, 0x6f, 0x72, 0x77, 0x61, - 0x72, 0x64, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x55, 0x6e, 0x6b, - 0x6e, 0x6f, 0x77, 0x6e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, - 0x46, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x69, 0x6e, 0x6b, 0x44, - 0x75, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x10, 0x05, 0x2a, 0x28, 0x0a, 0x08, 0x44, 0x65, - 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x10, - 0x00, 0x12, 0x07, 0x0a, 0x03, 0x45, 0x6e, 0x64, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x69, - 0x6e, 0x6b, 0x10, 0x02, 0x2a, 0x34, 0x0a, 0x09, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x10, 0x00, 0x12, 0x0d, - 0x0a, 0x09, 0x55, 0x6e, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x10, 0x01, 0x12, 0x0b, 0x0a, - 0x07, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x10, 0x02, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x7a, 0x69, 0x74, - 0x69, 0x2f, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x2f, 0x63, 0x74, 0x72, 0x6c, - 0x5f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x93, 0x08, 0x12, 0x1f, 0x0a, 0x1a, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x10, 0x9a, 0x08, 0x2a, 0x67, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x6f, 0x6e, 0x65, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x73, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x0a, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x10, 0x0b, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x69, 0x65, 0x73, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x0c, 0x2a, 0x3a, 0x0a, 0x10, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, + 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5a, 0x65, + 0x72, 0x6f, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x61, 0x6e, 0x61, + 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x10, 0x01, 0x2a, 0x35, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x6e, 0x75, 0x73, + 0x65, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4e, + 0x65, 0x77, 0x43, 0x74, 0x72, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x01, 0x2a, + 0x3d, 0x0a, 0x14, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x65, + 0x63, 0x65, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x02, 0x2a, 0x52, + 0x0a, 0x17, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x6e, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x15, 0x0a, + 0x11, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x6f, 0x72, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x10, 0x02, 0x2a, 0x83, 0x01, 0x0a, 0x0c, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x53, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x46, 0x61, + 0x75, 0x6c, 0x74, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x46, + 0x61, 0x75, 0x6c, 0x74, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x69, 0x6e, 0x6b, 0x46, 0x61, + 0x75, 0x6c, 0x74, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, + 0x46, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x46, 0x61, + 0x75, 0x6c, 0x74, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x69, 0x6e, 0x6b, 0x44, 0x75, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x10, 0x05, 0x2a, 0x28, 0x0a, 0x08, 0x44, 0x65, 0x73, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x10, 0x00, 0x12, + 0x07, 0x0a, 0x03, 0x45, 0x6e, 0x64, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x6b, + 0x10, 0x02, 0x2a, 0x34, 0x0a, 0x09, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x0b, 0x0a, 0x07, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, + 0x55, 0x6e, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x10, 0x02, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x7a, 0x69, 0x74, 0x69, 0x2f, + 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x2f, 0x63, 0x74, 0x72, 0x6c, 0x5f, 0x70, + 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2905,87 +2970,88 @@ func file_ctrl_proto_rawDescGZIP() []byte { return file_ctrl_proto_rawDescData } -var file_ctrl_proto_enumTypes = make([]protoimpl.EnumInfo, 8) +var file_ctrl_proto_enumTypes = make([]protoimpl.EnumInfo, 9) var file_ctrl_proto_msgTypes = make([]protoimpl.MessageInfo, 41) var file_ctrl_proto_goTypes = []interface{}{ (ContentType)(0), // 0: ziti.ctrl.pb.ContentType - (RouterCapability)(0), // 1: ziti.ctrl.pb.RouterCapability - (SettingTypes)(0), // 2: ziti.ctrl.pb.SettingTypes - (TerminatorPrecedence)(0), // 3: ziti.ctrl.pb.TerminatorPrecedence - (TerminatorInvalidReason)(0), // 4: ziti.ctrl.pb.TerminatorInvalidReason - (FaultSubject)(0), // 5: ziti.ctrl.pb.FaultSubject - (DestType)(0), // 6: ziti.ctrl.pb.DestType - (PeerState)(0), // 7: ziti.ctrl.pb.PeerState - (*Settings)(nil), // 8: ziti.ctrl.pb.Settings - (*CircuitRequest)(nil), // 9: ziti.ctrl.pb.CircuitRequest - (*CircuitConfirmation)(nil), // 10: ziti.ctrl.pb.CircuitConfirmation - (*CreateTerminatorRequest)(nil), // 11: ziti.ctrl.pb.CreateTerminatorRequest - (*RemoveTerminatorRequest)(nil), // 12: ziti.ctrl.pb.RemoveTerminatorRequest - (*RemoveTerminatorsRequest)(nil), // 13: ziti.ctrl.pb.RemoveTerminatorsRequest - (*Terminator)(nil), // 14: ziti.ctrl.pb.Terminator - (*ValidateTerminatorsRequest)(nil), // 15: ziti.ctrl.pb.ValidateTerminatorsRequest - (*ValidateTerminatorsV2Request)(nil), // 16: ziti.ctrl.pb.ValidateTerminatorsV2Request - (*RouterTerminatorState)(nil), // 17: ziti.ctrl.pb.RouterTerminatorState - (*ValidateTerminatorsV2Response)(nil), // 18: ziti.ctrl.pb.ValidateTerminatorsV2Response - (*UpdateTerminatorRequest)(nil), // 19: ziti.ctrl.pb.UpdateTerminatorRequest - (*Dial)(nil), // 20: ziti.ctrl.pb.Dial - (*LinkConn)(nil), // 21: ziti.ctrl.pb.LinkConn - (*LinkConnected)(nil), // 22: ziti.ctrl.pb.LinkConnected - (*RouterLinks)(nil), // 23: ziti.ctrl.pb.RouterLinks - (*Fault)(nil), // 24: ziti.ctrl.pb.Fault - (*Context)(nil), // 25: ziti.ctrl.pb.Context - (*Route)(nil), // 26: ziti.ctrl.pb.Route - (*Unroute)(nil), // 27: ziti.ctrl.pb.Unroute - (*InspectRequest)(nil), // 28: ziti.ctrl.pb.InspectRequest - (*InspectResponse)(nil), // 29: ziti.ctrl.pb.InspectResponse - (*VerifyRouter)(nil), // 30: ziti.ctrl.pb.VerifyRouter - (*Listener)(nil), // 31: ziti.ctrl.pb.Listener - (*Listeners)(nil), // 32: ziti.ctrl.pb.Listeners - (*UpdateCtrlAddresses)(nil), // 33: ziti.ctrl.pb.UpdateCtrlAddresses - (*PeerStateChange)(nil), // 34: ziti.ctrl.pb.PeerStateChange - (*PeerStateChanges)(nil), // 35: ziti.ctrl.pb.PeerStateChanges - (*RouterMetadata)(nil), // 36: ziti.ctrl.pb.RouterMetadata - nil, // 37: ziti.ctrl.pb.Settings.DataEntry - nil, // 38: ziti.ctrl.pb.CircuitRequest.PeerDataEntry - nil, // 39: ziti.ctrl.pb.CircuitConfirmation.IdleTimesEntry - nil, // 40: ziti.ctrl.pb.CreateTerminatorRequest.PeerDataEntry - nil, // 41: ziti.ctrl.pb.ValidateTerminatorsV2Response.StatesEntry - (*RouterLinks_RouterLink)(nil), // 42: ziti.ctrl.pb.RouterLinks.RouterLink - nil, // 43: ziti.ctrl.pb.Context.FieldsEntry - (*Route_Egress)(nil), // 44: ziti.ctrl.pb.Route.Egress - (*Route_Forward)(nil), // 45: ziti.ctrl.pb.Route.Forward - nil, // 46: ziti.ctrl.pb.Route.TagsEntry - nil, // 47: ziti.ctrl.pb.Route.Egress.PeerDataEntry - (*InspectResponse_InspectValue)(nil), // 48: ziti.ctrl.pb.InspectResponse.InspectValue + (ControlHeaders)(0), // 1: ziti.ctrl.pb.ControlHeaders + (RouterCapability)(0), // 2: ziti.ctrl.pb.RouterCapability + (SettingTypes)(0), // 3: ziti.ctrl.pb.SettingTypes + (TerminatorPrecedence)(0), // 4: ziti.ctrl.pb.TerminatorPrecedence + (TerminatorInvalidReason)(0), // 5: ziti.ctrl.pb.TerminatorInvalidReason + (FaultSubject)(0), // 6: ziti.ctrl.pb.FaultSubject + (DestType)(0), // 7: ziti.ctrl.pb.DestType + (PeerState)(0), // 8: ziti.ctrl.pb.PeerState + (*Settings)(nil), // 9: ziti.ctrl.pb.Settings + (*CircuitRequest)(nil), // 10: ziti.ctrl.pb.CircuitRequest + (*CircuitConfirmation)(nil), // 11: ziti.ctrl.pb.CircuitConfirmation + (*CreateTerminatorRequest)(nil), // 12: ziti.ctrl.pb.CreateTerminatorRequest + (*RemoveTerminatorRequest)(nil), // 13: ziti.ctrl.pb.RemoveTerminatorRequest + (*RemoveTerminatorsRequest)(nil), // 14: ziti.ctrl.pb.RemoveTerminatorsRequest + (*Terminator)(nil), // 15: ziti.ctrl.pb.Terminator + (*ValidateTerminatorsRequest)(nil), // 16: ziti.ctrl.pb.ValidateTerminatorsRequest + (*ValidateTerminatorsV2Request)(nil), // 17: ziti.ctrl.pb.ValidateTerminatorsV2Request + (*RouterTerminatorState)(nil), // 18: ziti.ctrl.pb.RouterTerminatorState + (*ValidateTerminatorsV2Response)(nil), // 19: ziti.ctrl.pb.ValidateTerminatorsV2Response + (*UpdateTerminatorRequest)(nil), // 20: ziti.ctrl.pb.UpdateTerminatorRequest + (*Dial)(nil), // 21: ziti.ctrl.pb.Dial + (*LinkConn)(nil), // 22: ziti.ctrl.pb.LinkConn + (*LinkConnected)(nil), // 23: ziti.ctrl.pb.LinkConnected + (*RouterLinks)(nil), // 24: ziti.ctrl.pb.RouterLinks + (*Fault)(nil), // 25: ziti.ctrl.pb.Fault + (*Context)(nil), // 26: ziti.ctrl.pb.Context + (*Route)(nil), // 27: ziti.ctrl.pb.Route + (*Unroute)(nil), // 28: ziti.ctrl.pb.Unroute + (*InspectRequest)(nil), // 29: ziti.ctrl.pb.InspectRequest + (*InspectResponse)(nil), // 30: ziti.ctrl.pb.InspectResponse + (*VerifyRouter)(nil), // 31: ziti.ctrl.pb.VerifyRouter + (*Listener)(nil), // 32: ziti.ctrl.pb.Listener + (*Listeners)(nil), // 33: ziti.ctrl.pb.Listeners + (*UpdateCtrlAddresses)(nil), // 34: ziti.ctrl.pb.UpdateCtrlAddresses + (*PeerStateChange)(nil), // 35: ziti.ctrl.pb.PeerStateChange + (*PeerStateChanges)(nil), // 36: ziti.ctrl.pb.PeerStateChanges + (*RouterMetadata)(nil), // 37: ziti.ctrl.pb.RouterMetadata + nil, // 38: ziti.ctrl.pb.Settings.DataEntry + nil, // 39: ziti.ctrl.pb.CircuitRequest.PeerDataEntry + nil, // 40: ziti.ctrl.pb.CircuitConfirmation.IdleTimesEntry + nil, // 41: ziti.ctrl.pb.CreateTerminatorRequest.PeerDataEntry + nil, // 42: ziti.ctrl.pb.ValidateTerminatorsV2Response.StatesEntry + (*RouterLinks_RouterLink)(nil), // 43: ziti.ctrl.pb.RouterLinks.RouterLink + nil, // 44: ziti.ctrl.pb.Context.FieldsEntry + (*Route_Egress)(nil), // 45: ziti.ctrl.pb.Route.Egress + (*Route_Forward)(nil), // 46: ziti.ctrl.pb.Route.Forward + nil, // 47: ziti.ctrl.pb.Route.TagsEntry + nil, // 48: ziti.ctrl.pb.Route.Egress.PeerDataEntry + (*InspectResponse_InspectValue)(nil), // 49: ziti.ctrl.pb.InspectResponse.InspectValue } var file_ctrl_proto_depIdxs = []int32{ - 37, // 0: ziti.ctrl.pb.Settings.data:type_name -> ziti.ctrl.pb.Settings.DataEntry - 38, // 1: ziti.ctrl.pb.CircuitRequest.peerData:type_name -> ziti.ctrl.pb.CircuitRequest.PeerDataEntry - 39, // 2: ziti.ctrl.pb.CircuitConfirmation.idleTimes:type_name -> ziti.ctrl.pb.CircuitConfirmation.IdleTimesEntry - 40, // 3: ziti.ctrl.pb.CreateTerminatorRequest.peerData:type_name -> ziti.ctrl.pb.CreateTerminatorRequest.PeerDataEntry - 3, // 4: ziti.ctrl.pb.CreateTerminatorRequest.precedence:type_name -> ziti.ctrl.pb.TerminatorPrecedence - 14, // 5: ziti.ctrl.pb.ValidateTerminatorsRequest.terminators:type_name -> ziti.ctrl.pb.Terminator - 14, // 6: ziti.ctrl.pb.ValidateTerminatorsV2Request.terminators:type_name -> ziti.ctrl.pb.Terminator - 4, // 7: ziti.ctrl.pb.RouterTerminatorState.reason:type_name -> ziti.ctrl.pb.TerminatorInvalidReason - 41, // 8: ziti.ctrl.pb.ValidateTerminatorsV2Response.states:type_name -> ziti.ctrl.pb.ValidateTerminatorsV2Response.StatesEntry - 3, // 9: ziti.ctrl.pb.UpdateTerminatorRequest.precedence:type_name -> ziti.ctrl.pb.TerminatorPrecedence - 21, // 10: ziti.ctrl.pb.LinkConnected.conns:type_name -> ziti.ctrl.pb.LinkConn - 42, // 11: ziti.ctrl.pb.RouterLinks.links:type_name -> ziti.ctrl.pb.RouterLinks.RouterLink - 5, // 12: ziti.ctrl.pb.Fault.subject:type_name -> ziti.ctrl.pb.FaultSubject - 43, // 13: ziti.ctrl.pb.Context.fields:type_name -> ziti.ctrl.pb.Context.FieldsEntry - 44, // 14: ziti.ctrl.pb.Route.egress:type_name -> ziti.ctrl.pb.Route.Egress - 45, // 15: ziti.ctrl.pb.Route.forwards:type_name -> ziti.ctrl.pb.Route.Forward - 25, // 16: ziti.ctrl.pb.Route.context:type_name -> ziti.ctrl.pb.Context - 46, // 17: ziti.ctrl.pb.Route.tags:type_name -> ziti.ctrl.pb.Route.TagsEntry - 48, // 18: ziti.ctrl.pb.InspectResponse.values:type_name -> ziti.ctrl.pb.InspectResponse.InspectValue - 31, // 19: ziti.ctrl.pb.Listeners.listeners:type_name -> ziti.ctrl.pb.Listener - 7, // 20: ziti.ctrl.pb.PeerStateChange.state:type_name -> ziti.ctrl.pb.PeerState - 31, // 21: ziti.ctrl.pb.PeerStateChange.listeners:type_name -> ziti.ctrl.pb.Listener - 34, // 22: ziti.ctrl.pb.PeerStateChanges.changes:type_name -> ziti.ctrl.pb.PeerStateChange - 1, // 23: ziti.ctrl.pb.RouterMetadata.capabilities:type_name -> ziti.ctrl.pb.RouterCapability - 17, // 24: ziti.ctrl.pb.ValidateTerminatorsV2Response.StatesEntry.value:type_name -> ziti.ctrl.pb.RouterTerminatorState - 47, // 25: ziti.ctrl.pb.Route.Egress.peerData:type_name -> ziti.ctrl.pb.Route.Egress.PeerDataEntry - 6, // 26: ziti.ctrl.pb.Route.Forward.dstType:type_name -> ziti.ctrl.pb.DestType + 38, // 0: ziti.ctrl.pb.Settings.data:type_name -> ziti.ctrl.pb.Settings.DataEntry + 39, // 1: ziti.ctrl.pb.CircuitRequest.peerData:type_name -> ziti.ctrl.pb.CircuitRequest.PeerDataEntry + 40, // 2: ziti.ctrl.pb.CircuitConfirmation.idleTimes:type_name -> ziti.ctrl.pb.CircuitConfirmation.IdleTimesEntry + 41, // 3: ziti.ctrl.pb.CreateTerminatorRequest.peerData:type_name -> ziti.ctrl.pb.CreateTerminatorRequest.PeerDataEntry + 4, // 4: ziti.ctrl.pb.CreateTerminatorRequest.precedence:type_name -> ziti.ctrl.pb.TerminatorPrecedence + 15, // 5: ziti.ctrl.pb.ValidateTerminatorsRequest.terminators:type_name -> ziti.ctrl.pb.Terminator + 15, // 6: ziti.ctrl.pb.ValidateTerminatorsV2Request.terminators:type_name -> ziti.ctrl.pb.Terminator + 5, // 7: ziti.ctrl.pb.RouterTerminatorState.reason:type_name -> ziti.ctrl.pb.TerminatorInvalidReason + 42, // 8: ziti.ctrl.pb.ValidateTerminatorsV2Response.states:type_name -> ziti.ctrl.pb.ValidateTerminatorsV2Response.StatesEntry + 4, // 9: ziti.ctrl.pb.UpdateTerminatorRequest.precedence:type_name -> ziti.ctrl.pb.TerminatorPrecedence + 22, // 10: ziti.ctrl.pb.LinkConnected.conns:type_name -> ziti.ctrl.pb.LinkConn + 43, // 11: ziti.ctrl.pb.RouterLinks.links:type_name -> ziti.ctrl.pb.RouterLinks.RouterLink + 6, // 12: ziti.ctrl.pb.Fault.subject:type_name -> ziti.ctrl.pb.FaultSubject + 44, // 13: ziti.ctrl.pb.Context.fields:type_name -> ziti.ctrl.pb.Context.FieldsEntry + 45, // 14: ziti.ctrl.pb.Route.egress:type_name -> ziti.ctrl.pb.Route.Egress + 46, // 15: ziti.ctrl.pb.Route.forwards:type_name -> ziti.ctrl.pb.Route.Forward + 26, // 16: ziti.ctrl.pb.Route.context:type_name -> ziti.ctrl.pb.Context + 47, // 17: ziti.ctrl.pb.Route.tags:type_name -> ziti.ctrl.pb.Route.TagsEntry + 49, // 18: ziti.ctrl.pb.InspectResponse.values:type_name -> ziti.ctrl.pb.InspectResponse.InspectValue + 32, // 19: ziti.ctrl.pb.Listeners.listeners:type_name -> ziti.ctrl.pb.Listener + 8, // 20: ziti.ctrl.pb.PeerStateChange.state:type_name -> ziti.ctrl.pb.PeerState + 32, // 21: ziti.ctrl.pb.PeerStateChange.listeners:type_name -> ziti.ctrl.pb.Listener + 35, // 22: ziti.ctrl.pb.PeerStateChanges.changes:type_name -> ziti.ctrl.pb.PeerStateChange + 2, // 23: ziti.ctrl.pb.RouterMetadata.capabilities:type_name -> ziti.ctrl.pb.RouterCapability + 18, // 24: ziti.ctrl.pb.ValidateTerminatorsV2Response.StatesEntry.value:type_name -> ziti.ctrl.pb.RouterTerminatorState + 48, // 25: ziti.ctrl.pb.Route.Egress.peerData:type_name -> ziti.ctrl.pb.Route.Egress.PeerDataEntry + 7, // 26: ziti.ctrl.pb.Route.Forward.dstType:type_name -> ziti.ctrl.pb.DestType 27, // [27:27] is the sub-list for method output_type 27, // [27:27] is the sub-list for method input_type 27, // [27:27] is the sub-list for extension type_name @@ -3401,7 +3467,7 @@ func file_ctrl_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_ctrl_proto_rawDesc, - NumEnums: 8, + NumEnums: 9, NumMessages: 41, NumExtensions: 0, NumServices: 0, diff --git a/common/pb/ctrl_pb/ctrl.proto b/common/pb/ctrl_pb/ctrl.proto index f0bea8548..3d1d1d954 100644 --- a/common/pb/ctrl_pb/ctrl.proto +++ b/common/pb/ctrl_pb/ctrl.proto @@ -41,7 +41,10 @@ enum ContentType { DecommissionRouterRequestType = 1043; PeerStateChangeRequestType = 1050; +} +enum ControlHeaders { + NoneHeader = 0; ListenersHeader = 10; RouterMetadataHeader = 11; CapabilitiesHeader = 12; @@ -167,6 +170,7 @@ message RouterLinks { string linkProtocol = 3; repeated string linkCostTags = 4; string dialAddress = 5; + uint32 iteration = 6; } repeated RouterLink links = 1; @@ -184,6 +188,7 @@ enum FaultSubject { message Fault { FaultSubject subject = 1; string id = 2; + uint32 iteration = 3; } message Context { diff --git a/common/pb/ctrl_pb/decoder.go b/common/pb/ctrl_pb/decoder.go index 680501c85..d241f1101 100644 --- a/common/pb/ctrl_pb/decoder.go +++ b/common/pb/ctrl_pb/decoder.go @@ -20,8 +20,8 @@ import ( "fmt" "github.com/michaelquigley/pfxlog" "github.com/openziti/channel/v2" - "github.com/openziti/ziti/common/ctrl_msg" "github.com/openziti/metrics/metrics_pb" + "github.com/openziti/ziti/common/ctrl_msg" "google.golang.org/protobuf/proto" "strconv" "strings" @@ -226,6 +226,7 @@ func (d Decoder) Decode(msg *channel.Message) ([]byte, bool) { meta := channel.NewTraceMessageDecode(DECODER, "Fault") meta["subject"] = fault.Subject.String() meta["id"] = fault.Id + meta["iteration"] = fault.Iteration data, err := meta.MarshalTraceMessageDecode() if err != nil { diff --git a/common/pb/mgmt_pb/mgmt.pb.go b/common/pb/mgmt_pb/mgmt.pb.go index d5b956ab8..2af6cd8ad 100644 --- a/common/pb/mgmt_pb/mgmt.pb.go +++ b/common/pb/mgmt_pb/mgmt.pb.go @@ -1552,6 +1552,8 @@ type RouterLinkDetail struct { RouterState LinkState `protobuf:"varint,3,opt,name=routerState,proto3,enum=ziti.mgmt_pb.LinkState" json:"routerState,omitempty"` DestConnected bool `protobuf:"varint,4,opt,name=destConnected,proto3" json:"destConnected,omitempty"` IsValid bool `protobuf:"varint,5,opt,name=isValid,proto3" json:"isValid,omitempty"` + DestRouterId string `protobuf:"bytes,6,opt,name=destRouterId,proto3" json:"destRouterId,omitempty"` + Dialed bool `protobuf:"varint,7,opt,name=dialed,proto3" json:"dialed,omitempty"` } func (x *RouterLinkDetail) Reset() { @@ -1621,6 +1623,20 @@ func (x *RouterLinkDetail) GetIsValid() bool { return false } +func (x *RouterLinkDetail) GetDestRouterId() string { + if x != nil { + return x.DestRouterId + } + return "" +} + +func (x *RouterLinkDetail) GetDialed() bool { + if x != nil { + return x.Dialed + } + return false +} + type StreamMetricsRequest_MetricMatcher struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2037,7 +2053,7 @@ var file_mgmt_proto_rawDesc = []byte{ 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0b, 0x6c, 0x69, 0x6e, - 0x6b, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0xdc, 0x01, 0x0a, 0x10, 0x52, 0x6f, 0x75, + 0x6b, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x98, 0x02, 0x0a, 0x10, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x64, 0x12, 0x35, 0x0a, 0x09, 0x63, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x61, @@ -2051,104 +2067,108 @@ var file_mgmt_proto_rawDesc = []byte{ 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x64, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x2a, 0x95, 0x08, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x65, 0x72, 0x6f, 0x10, - 0x00, 0x12, 0x1c, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb8, 0x4e, 0x12, - 0x1a, 0x0a, 0x15, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb9, 0x4e, 0x12, 0x20, 0x0a, 0x1b, 0x54, - 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x50, 0x69, 0x70, 0x65, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbc, 0x4e, 0x12, 0x23, 0x0a, - 0x1e, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x54, 0x72, - 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, - 0xbd, 0x4e, 0x12, 0x1c, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x72, 0x61, 0x63, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbe, 0x4e, - 0x12, 0x1a, 0x0a, 0x15, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbf, 0x4e, 0x12, 0x17, 0x0a, 0x12, - 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x10, 0xc0, 0x4e, 0x12, 0x18, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xc1, 0x4e, 0x12, - 0x1a, 0x0a, 0x15, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x44, 0x62, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xd6, 0x4e, 0x12, 0x25, 0x0a, 0x20, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x74, - 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, - 0xd7, 0x4e, 0x12, 0x2c, 0x0a, 0x27, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, - 0x67, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x43, 0x74, 0x72, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, - 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xd8, 0x4e, - 0x12, 0x26, 0x0a, 0x21, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xd9, 0x4e, 0x12, 0x2e, 0x0a, 0x29, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x44, 0x75, 0x6d, 0x70, 0x46, 0x6f, 0x72, 0x77, 0x61, - 0x72, 0x64, 0x65, 0x72, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xda, 0x4e, 0x12, 0x24, 0x0a, 0x1f, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x44, 0x75, 0x6d, 0x70, 0x4c, 0x69, 0x6e, 0x6b, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdb, 0x4e, 0x12, 0x22, - 0x0a, 0x1d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x55, 0x6e, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, - 0xdc, 0x4e, 0x12, 0x1d, 0x0a, 0x18, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x51, 0x75, 0x69, 0x65, - 0x73, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdd, - 0x4e, 0x12, 0x1f, 0x0a, 0x1a, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x71, 0x75, 0x69, - 0x65, 0x73, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, - 0xde, 0x4e, 0x12, 0x22, 0x0a, 0x1d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x63, 0x6f, - 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x10, 0xdf, 0x4e, 0x12, 0x1f, 0x0a, 0x1a, 0x52, 0x61, 0x66, 0x74, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x10, 0xe0, 0x4e, 0x12, 0x20, 0x0a, 0x1b, 0x52, 0x61, 0x66, 0x74, 0x4c, - 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe1, 0x4e, 0x12, 0x1b, 0x0a, 0x16, 0x52, 0x61, 0x66, - 0x74, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x10, 0xe2, 0x4e, 0x12, 0x1e, 0x0a, 0x19, 0x52, 0x61, 0x66, 0x74, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x10, 0xe3, 0x4e, 0x12, 0x26, 0x0a, 0x21, 0x52, 0x61, 0x66, 0x74, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe4, 0x4e, 0x12, 0x13, - 0x0a, 0x0e, 0x52, 0x61, 0x66, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x44, 0x62, - 0x10, 0xe5, 0x4e, 0x12, 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, - 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf4, 0x4e, 0x12, 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf5, 0x4e, 0x12, 0x21, 0x0a, - 0x1c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, - 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf6, 0x4e, - 0x12, 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x10, 0xf7, 0x4e, 0x12, 0x24, 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf8, 0x4e, 0x12, 0x22, 0x0a, 0x1d, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, - 0x6b, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf9, 0x4e, 0x2a, - 0x53, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x6f, 0x6e, - 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x0a, 0x12, 0x12, - 0x0a, 0x0e, 0x43, 0x74, 0x72, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, - 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x64, 0x10, 0x0c, 0x2a, 0x78, 0x0a, 0x16, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x69, - 0x72, 0x63, 0x75, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, - 0x0a, 0x0e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x64, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, - 0x74, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x61, - 0x74, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x43, - 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x04, 0x2a, 0x2b, - 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x58, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0b, - 0x0a, 0x07, 0x49, 0x4e, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x01, 0x2a, 0x77, 0x0a, 0x0f, 0x54, - 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x09, - 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, - 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, - 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x55, 0x6e, 0x6b, 0x6e, - 0x6f, 0x77, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x10, 0x03, 0x12, - 0x13, 0x0a, 0x0f, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x61, 0x64, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x10, 0x04, 0x2a, 0x53, 0x0a, 0x09, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, - 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x69, 0x6e, 0x6b, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, - 0x69, 0x73, 0x68, 0x65, 0x64, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x50, - 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, - 0x44, 0x69, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x10, 0x03, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x7a, 0x69, 0x74, 0x69, - 0x2f, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x2f, 0x6d, 0x67, 0x6d, 0x74, 0x5f, - 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x52, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, + 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x64, + 0x69, 0x61, 0x6c, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x69, 0x61, + 0x6c, 0x65, 0x64, 0x2a, 0x95, 0x08, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x65, 0x72, 0x6f, 0x10, 0x00, 0x12, 0x1c, 0x0a, + 0x17, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb8, 0x4e, 0x12, 0x1a, 0x0a, 0x15, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x10, 0xb9, 0x4e, 0x12, 0x20, 0x0a, 0x1b, 0x54, 0x6f, 0x67, 0x67, 0x6c, + 0x65, 0x50, 0x69, 0x70, 0x65, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbc, 0x4e, 0x12, 0x23, 0x0a, 0x1e, 0x54, 0x6f, 0x67, + 0x67, 0x6c, 0x65, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbd, 0x4e, 0x12, 0x1c, + 0x0a, 0x17, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbe, 0x4e, 0x12, 0x1a, 0x0a, 0x15, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbf, 0x4e, 0x12, 0x17, 0x0a, 0x12, 0x49, 0x6e, 0x73, 0x70, + 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xc0, + 0x4e, 0x12, 0x18, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xc1, 0x4e, 0x12, 0x1a, 0x0a, 0x15, 0x53, + 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x44, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x10, 0xd6, 0x4e, 0x12, 0x25, 0x0a, 0x20, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xd7, 0x4e, 0x12, 0x2c, + 0x0a, 0x27, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x54, 0x6f, 0x67, + 0x67, 0x6c, 0x65, 0x43, 0x74, 0x72, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xd8, 0x4e, 0x12, 0x26, 0x0a, 0x21, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x10, 0xd9, 0x4e, 0x12, 0x2e, 0x0a, 0x29, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, + 0x62, 0x75, 0x67, 0x44, 0x75, 0x6d, 0x70, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x10, 0xda, 0x4e, 0x12, 0x24, 0x0a, 0x1f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, + 0x62, 0x75, 0x67, 0x44, 0x75, 0x6d, 0x70, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdb, 0x4e, 0x12, 0x22, 0x0a, 0x1d, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x55, 0x6e, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdc, 0x4e, 0x12, 0x1d, + 0x0a, 0x18, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x51, 0x75, 0x69, 0x65, 0x73, 0x63, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdd, 0x4e, 0x12, 0x1f, 0x0a, + 0x1a, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x71, 0x75, 0x69, 0x65, 0x73, 0x63, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xde, 0x4e, 0x12, 0x22, + 0x0a, 0x1d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, + 0xdf, 0x4e, 0x12, 0x1f, 0x0a, 0x1a, 0x52, 0x61, 0x66, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x10, 0xe0, 0x4e, 0x12, 0x20, 0x0a, 0x1b, 0x52, 0x61, 0x66, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x10, 0xe1, 0x4e, 0x12, 0x1b, 0x0a, 0x16, 0x52, 0x61, 0x66, 0x74, 0x41, 0x64, 0x64, + 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, + 0xe2, 0x4e, 0x12, 0x1e, 0x0a, 0x19, 0x52, 0x61, 0x66, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, + 0xe3, 0x4e, 0x12, 0x26, 0x0a, 0x21, 0x52, 0x61, 0x66, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x65, 0x72, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe4, 0x4e, 0x12, 0x13, 0x0a, 0x0e, 0x52, 0x61, + 0x66, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x44, 0x62, 0x10, 0xe5, 0x4e, 0x12, + 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x10, 0xf4, 0x4e, 0x12, 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf5, 0x4e, 0x12, 0x21, 0x0a, 0x1c, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf6, 0x4e, 0x12, 0x23, 0x0a, 0x1e, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, + 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf7, + 0x4e, 0x12, 0x24, 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x10, 0xf8, 0x4e, 0x12, 0x22, 0x0a, 0x1d, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf9, 0x4e, 0x2a, 0x53, 0x0a, 0x06, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x6f, 0x6e, 0x65, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x74, + 0x72, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x10, 0x0b, 0x12, 0x10, + 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x10, 0x0c, + 0x2a, 0x78, 0x0a, 0x16, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, + 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x69, + 0x72, 0x63, 0x75, 0x69, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x10, 0x00, 0x12, 0x12, + 0x0a, 0x0e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, + 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x50, 0x72, 0x65, + 0x73, 0x65, 0x6e, 0x74, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x61, 0x74, 0x68, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x69, 0x72, 0x63, 0x75, + 0x69, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x04, 0x2a, 0x2b, 0x0a, 0x0f, 0x54, 0x72, + 0x61, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, + 0x07, 0x45, 0x58, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, + 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x01, 0x2a, 0x77, 0x0a, 0x0f, 0x54, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x55, 0x6e, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x02, 0x12, 0x1c, 0x0a, + 0x18, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x49, + 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x10, 0x04, + 0x2a, 0x53, 0x0a, 0x09, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0f, 0x0a, + 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x13, + 0x0a, 0x0f, 0x4c, 0x69, 0x6e, 0x6b, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, + 0x64, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x44, 0x69, 0x61, 0x6c, + 0x69, 0x6e, 0x67, 0x10, 0x03, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x7a, 0x69, 0x74, 0x69, 0x2f, 0x66, 0x61, 0x62, + 0x72, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x2f, 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/common/pb/mgmt_pb/mgmt.proto b/common/pb/mgmt_pb/mgmt.proto index fa816d61f..7290097a1 100644 --- a/common/pb/mgmt_pb/mgmt.proto +++ b/common/pb/mgmt_pb/mgmt.proto @@ -234,4 +234,6 @@ message RouterLinkDetail { LinkState routerState = 3; bool destConnected = 4; bool isValid = 5; + string destRouterId = 6; + bool dialed = 7; } diff --git a/controller/api_impl/circuit_router.go b/controller/api_impl/circuit_router.go index 964f15d2d..d12209ffc 100644 --- a/controller/api_impl/circuit_router.go +++ b/controller/api_impl/circuit_router.go @@ -63,6 +63,10 @@ func (r *CircuitRouter) ListCircuits(n *network.Network, rc api.RequestContext) return nil, err } + if query.GetLimit() == nil { + query.SetLimit(10) + } + circuits, count, err := n.GetCircuitStore().QueryEntitiesC(query) if err != nil { return nil, err diff --git a/controller/api_impl/link_api_model.go b/controller/api_impl/link_api_model.go index 97c720505..2059df50d 100644 --- a/controller/api_impl/link_api_model.go +++ b/controller/api_impl/link_api_model.go @@ -41,7 +41,8 @@ func (factory *LinkLinkFactoryIml) Links(entity LinkEntity) rest_model.Links { return links } -func MapLinkToRestModel(_ *network.Network, _ api.RequestContext, link *network.Link) (*rest_model.LinkDetail, error) { +func MapLinkToRestModel(n *network.Network, _ api.RequestContext, link *network.Link) (*rest_model.LinkDetail, error) { + iteration := int64(link.Iteration) staticCost := int64(link.StaticCost) linkState := link.CurrentState() linkStateStr := "" @@ -51,10 +52,19 @@ func MapLinkToRestModel(_ *network.Network, _ api.RequestContext, link *network. down := link.IsDown() + destRouter := link.GetDest() + if destRouter == nil { + var err error + destRouter, err = n.Routers.Read(link.DstId) + if err != nil { + return nil, err + } + } + ret := &rest_model.LinkDetail{ Cost: &link.Cost, DestLatency: &link.DstLatency, - DestRouter: ToEntityRef(link.Dst.Name, link.Dst, RouterLinkFactory), + DestRouter: ToEntityRef(destRouter.Name, destRouter, RouterLinkFactory), Down: &down, ID: &link.Id, SourceLatency: &link.SrcLatency, @@ -62,6 +72,7 @@ func MapLinkToRestModel(_ *network.Network, _ api.RequestContext, link *network. State: &linkStateStr, StaticCost: &staticCost, Protocol: &link.Protocol, + Iteration: &iteration, } return ret, nil } diff --git a/controller/api_impl/link_router.go b/controller/api_impl/link_router.go index 910ee534d..cf2e6062c 100644 --- a/controller/api_impl/link_router.go +++ b/controller/api_impl/link_router.go @@ -68,6 +68,10 @@ func (r *LinkRouter) ListLinks(n *network.Network, rc api.RequestContext) { return nil, err } + if query.GetLimit() == nil { + query.SetLimit(10) + } + links, count, err := n.GetLinkStore().QueryEntitiesC(query) if err != nil { return nil, err diff --git a/controller/controller.go b/controller/controller.go index 00931edc9..5c3cf0eab 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -264,9 +264,10 @@ func (c *Controller) Run() error { capabilityMask := &big.Int{} capabilityMask.SetBit(capabilityMask, capabilities.ControllerCreateTerminatorV2, 1) + capabilityMask.SetBit(capabilityMask, capabilities.ControllerSingleRouterLinkSource, 1) headers := map[int32][]byte{ - channel.HelloVersionHeader: versionHeader, - int32(ctrl_pb.ContentType_CapabilitiesHeader): capabilityMask.Bytes(), + channel.HelloVersionHeader: versionHeader, + int32(ctrl_pb.ControlHeaders_CapabilitiesHeader): capabilityMask.Bytes(), } if c.raftController != nil { diff --git a/controller/events/metrics_mappers.go b/controller/events/metrics_mappers.go index a957d1589..acb5783a6 100644 --- a/controller/events/metrics_mappers.go +++ b/controller/events/metrics_mappers.go @@ -58,7 +58,7 @@ func (self *linkMetricsMapper) mapMetrics(_ *metrics_pb.MetricsMessage, event *e event.Tags[k] = v } event.Tags["sourceRouterId"] = link.Src.Id - event.Tags["targetRouterId"] = link.Dst.Id + event.Tags["targetRouterId"] = link.DstId } } } diff --git a/controller/handler_ctrl/accept.go b/controller/handler_ctrl/accept.go index 50b9f14c0..78d4279e5 100644 --- a/controller/handler_ctrl/accept.go +++ b/controller/handler_ctrl/accept.go @@ -87,7 +87,7 @@ func (self *CtrlAccepter) Bind(binding channel.Binding) error { } r.Listeners = nil - if val, found := ch.Underlay().Headers()[int32(ctrl_pb.ContentType_ListenersHeader)]; found { + if val, found := ch.Underlay().Headers()[int32(ctrl_pb.ControlHeaders_ListenersHeader)]; found { listeners := &ctrl_pb.Listeners{} if err = proto.Unmarshal(val, listeners); err != nil { log.WithError(err).Error("unable to unmarshall listeners value") @@ -104,7 +104,7 @@ func (self *CtrlAccepter) Bind(binding channel.Binding) error { log.Debug("no advertised listeners") } - if val, found := ch.Underlay().Headers()[int32(ctrl_pb.ContentType_RouterMetadataHeader)]; found { + if val, found := ch.Underlay().Headers()[int32(ctrl_pb.ControlHeaders_RouterMetadataHeader)]; found { routerMetadata := &ctrl_pb.RouterMetadata{} if err = proto.Unmarshal(val, routerMetadata); err != nil { log.WithError(err).Error("unable to unmarshall router metadata value") diff --git a/controller/handler_ctrl/fault.go b/controller/handler_ctrl/fault.go index 18333b460..ab040c946 100644 --- a/controller/handler_ctrl/fault.go +++ b/controller/handler_ctrl/fault.go @@ -21,9 +21,9 @@ import ( "github.com/michaelquigley/pfxlog" "github.com/openziti/channel/v2" "github.com/openziti/channel/v2/protobufs" + "github.com/openziti/ziti/common/pb/ctrl_pb" "github.com/openziti/ziti/controller/event" "github.com/openziti/ziti/controller/network" - "github.com/openziti/ziti/common/pb/ctrl_pb" "github.com/sirupsen/logrus" "google.golang.org/protobuf/proto" "strings" @@ -55,7 +55,7 @@ func (h *faultHandler) HandleReceive(msg *channel.Message, ch channel.Channel) { } func (h *faultHandler) handleFault(_ *channel.Message, ch channel.Channel, fault *ctrl_pb.Fault) { - log := pfxlog.ContextLogger(ch.Label()).Entry + log := pfxlog.ContextLogger(ch.Label()).WithField("routerId", h.r.Id) switch fault.Subject { case ctrl_pb.FaultSubject_LinkFault: @@ -110,17 +110,25 @@ func (h *faultHandler) handleFault(_ *channel.Message, ch channel.Channel, fault func (h *faultHandler) handleFaultedLink(log *logrus.Entry, fault *ctrl_pb.Fault) { linkId := fault.Id + log = log.WithField("linkId", linkId).WithField("fault.iteration", fault.Iteration) + if link, found := h.network.GetLink(linkId); found { - log = log.WithField("linkId", linkId) + log = log.WithField("link.iteration", link.Iteration) + + if fault.Iteration != 0 && link.Iteration != 0 && fault.Iteration < link.Iteration { + log.Info("fault reported, but iteration is older than current link, ignoring") + return + } + wasConnected := link.IsUsable() - if err := h.network.LinkFaulted(linkId, fault.Subject == ctrl_pb.FaultSubject_LinkDuplicate); err == nil { + if err := h.network.LinkFaulted(link, fault.Subject == ctrl_pb.FaultSubject_LinkDuplicate); err == nil { h.network.LinkChanged(link) otherRouter := link.Src if link.Src.Id == h.r.Id { - otherRouter = link.Dst + otherRouter = link.GetDest() } - if wasConnected { + if wasConnected && otherRouter != nil { fault.Subject = ctrl_pb.FaultSubject_LinkFault if ctrl := otherRouter.Control; ctrl != nil && otherRouter.Connected.Load() { if err := protobufs.MarshalTyped(fault).Send(ctrl); err != nil { @@ -135,7 +143,7 @@ func (h *faultHandler) handleFaultedLink(log *logrus.Entry, fault *ctrl_pb.Fault log.WithError(err).Error("error handling link fault") } } else { + log.Info("link fault for unknown link") h.network.NotifyLinkIdEvent(linkId, event.LinkFault) } - } diff --git a/controller/handler_ctrl/router_link.go b/controller/handler_ctrl/router_link.go index be3d59fa1..dc1bd71cc 100644 --- a/controller/handler_ctrl/router_link.go +++ b/controller/handler_ctrl/router_link.go @@ -51,6 +51,6 @@ func (h *routerLinkHandler) HandleReceive(msg *channel.Message, ch channel.Chann func (h *routerLinkHandler) HandleLinks(links *ctrl_pb.RouterLinks) { for _, link := range links.Links { - h.network.NotifyExistingLink(link.Id, link.LinkProtocol, link.DialAddress, h.r, link.DestRouterId) + h.network.NotifyExistingLink(link.Id, link.Iteration, link.LinkProtocol, link.DialAddress, h.r, link.DestRouterId) } } diff --git a/controller/network/assembly.go b/controller/network/assembly.go index f171b9e14..0a8bf5213 100644 --- a/controller/network/assembly.go +++ b/controller/network/assembly.go @@ -19,9 +19,9 @@ package network import ( "github.com/michaelquigley/pfxlog" "github.com/openziti/channel/v2/protobufs" - "github.com/openziti/ziti/controller/event" - "github.com/openziti/ziti/common/pb/ctrl_pb" "github.com/openziti/foundation/v2/info" + "github.com/openziti/ziti/common/pb/ctrl_pb" + "github.com/openziti/ziti/controller/event" "time" ) @@ -43,23 +43,23 @@ func (network *Network) assemble() { dial := &ctrl_pb.Dial{ LinkId: missingLink.Id, Address: missingLink.DialAddress, - RouterId: missingLink.Dst.Id, + RouterId: missingLink.DstId, LinkProtocol: missingLink.Protocol, } - if versionInfo := missingLink.Dst.VersionInfo; versionInfo != nil { - dial.RouterVersion = missingLink.Dst.VersionInfo.Version + if versionInfo := missingLink.GetDest().VersionInfo; versionInfo != nil { + dial.RouterVersion = missingLink.GetDest().VersionInfo.Version } if err = protobufs.MarshalTyped(dial).Send(missingLink.Src.Control); err != nil { log.WithField("linkId", missingLink.Id). WithField("srcRouterId", missingLink.Src.Id). - WithField("dstRouterId", missingLink.Dst.Id). + WithField("dstRouterId", missingLink.DstId). WithError(err).Error("unexpected error sending dial") } else { log.WithField("linkId", missingLink.Id). WithField("srcRouterId", missingLink.Src.Id). - WithField("dstRouterId", missingLink.Dst.Id). + WithField("dstRouterId", missingLink.DstId). Info("sending link dial") network.NotifyLinkEvent(missingLink, event.LinkDialed) } @@ -79,7 +79,7 @@ func (network *Network) NotifyLinkEvent(link *Link, eventType event.LinkEventTyp Timestamp: time.Now(), LinkId: link.Id, SrcRouterId: link.Src.Id, - DstRouterId: link.Dst.Id, + DstRouterId: link.DstId, Protocol: link.Protocol, Cost: link.GetStaticCost(), DialAddress: link.DialAddress, @@ -94,7 +94,7 @@ func (network *Network) NotifyLinkConnected(link *Link, msg *ctrl_pb.LinkConnect Timestamp: time.Now(), LinkId: link.Id, SrcRouterId: link.Src.Id, - DstRouterId: link.Dst.Id, + DstRouterId: link.DstId, Protocol: link.Protocol, Cost: link.GetStaticCost(), DialAddress: link.DialAddress, diff --git a/controller/network/link.go b/controller/network/link.go index ec25a40e5..db56db3dd 100644 --- a/controller/network/link.go +++ b/controller/network/link.go @@ -17,6 +17,7 @@ package network import ( + "github.com/openziti/foundation/v2/concurrenz" "github.com/openziti/foundation/v2/info" "sync" "sync/atomic" @@ -28,8 +29,10 @@ type Link struct { DstLatency int64 Cost int64 Id string + Iteration uint32 Src *Router - Dst *Router + DstId string + Dst concurrenz.AtomicValue[*Router] Protocol string DialAddress string state []*LinkState @@ -59,6 +62,10 @@ func (link *Link) GetId() string { return link.Id } +func (link *Link) GetDest() *Router { + return link.Dst.Load() +} + func (link *Link) CurrentState() *LinkState { link.lock.Lock() defer link.lock.Unlock() diff --git a/controller/network/link_controller.go b/controller/network/link_controller.go index d1bc5df26..599680fe2 100644 --- a/controller/network/link_controller.go +++ b/controller/network/link_controller.go @@ -19,6 +19,7 @@ package network import ( "encoding/json" "errors" + "github.com/michaelquigley/pfxlog" "github.com/openziti/channel/v2/protobufs" "github.com/openziti/foundation/v2/info" "github.com/openziti/storage/objectz" @@ -70,7 +71,7 @@ func newLinkController(options *Options) *linkController { return &entity.Src.Id }) result.store.AddStringSymbol("destRouter", func(entity *Link) *string { - return &entity.Dst.Id + return &entity.DstId }) result.store.AddInt64Symbol("cost", func(entity *Link) *int64 { val := entity.GetCost() @@ -95,31 +96,62 @@ func newLinkController(options *Options) *linkController { } return nil }) + result.store.AddInt64Symbol("iteration", func(entity *Link) *int64 { + val := int64(entity.Iteration) + return &val + }) return result } +func (linkController *linkController) buildRouterLinks(router *Router) { + for entry := range linkController.linkTable.links.IterBuffered() { + link := entry.Val + if link.DstId == router.Id { + router.routerLinks.Add(link, link.Src.Id) + link.Dst.Store(router) + } + } +} + func (linkController *linkController) add(link *Link) { linkController.linkTable.add(link) - link.Src.routerLinks.Add(link, link.Dst) - link.Dst.routerLinks.Add(link, link.Src) + link.Src.routerLinks.Add(link, link.DstId) + if dest := link.GetDest(); dest != nil { + dest.routerLinks.Add(link, link.Src.Id) + } } func (linkController *linkController) has(link *Link) bool { return linkController.linkTable.has(link) } -func (linkController *linkController) routerReportedLink(linkId, linkProtocol, dialAddress string, src, dst *Router) (*Link, bool) { +func (linkController *linkController) routerReportedLink(linkId string, iteration uint32, linkProtocol, dialAddress string, src, dst *Router, dstId string) (*Link, bool) { linkController.lock.Lock() defer linkController.lock.Unlock() - if link, found := linkController.get(linkId); found { + link, _ := linkController.get(linkId) + if link != nil && link.Iteration >= iteration { return link, false } - link := newLink(linkId, linkProtocol, dialAddress, linkController.initialLatency) + // remove the older link before adding the new one + if link != nil { + log := pfxlog.Logger(). + WithField("routerId", src.Id). + WithField("linkId", linkId). + WithField("destRouterId", dstId). + WithField("iteration", iteration) + + linkController.remove(link) + log.Infof("replaced link with newer iteration %v => %v", link.Iteration, iteration) + } + + link = newLink(linkId, linkProtocol, dialAddress, linkController.initialLatency) + link.Iteration = iteration link.Src = src - link.Dst = dst + link.Dst.Store(dst) + link.DstId = dstId link.addState(newLinkState(Connected)) linkController.add(link) return link, true @@ -134,9 +166,12 @@ func (linkController *linkController) all() []*Link { } func (linkController *linkController) remove(link *Link) { - linkController.linkTable.remove(link) - link.Src.routerLinks.Remove(link, link.Dst) - link.Dst.routerLinks.Remove(link, link.Src) + if linkController.linkTable.remove(link) { + link.Src.routerLinks.Remove(link, link.DstId) + if dest := link.GetDest(); dest != nil { + dest.routerLinks.Remove(link, link.Src.Id) + } + } } func (linkController *linkController) connectedNeighborsOfRouter(router *Router) []*Router { @@ -144,12 +179,13 @@ func (linkController *linkController) connectedNeighborsOfRouter(router *Router) links := router.routerLinks.GetLinks() for _, link := range links { - if link.IsUsable() { - if link.Src != router { + dstRouter := link.GetDest() + if dstRouter != nil && dstRouter.Connected.Load() && link.IsUsable() { + if link.Src.Id != router.Id { neighborMap[link.Src.Id] = link.Src } - if link.Dst != router { - neighborMap[link.Dst.Id] = link.Dst + if link.DstId != router.Id { + neighborMap[link.DstId] = dstRouter } } } @@ -170,7 +206,7 @@ func (linkController *linkController) leastExpensiveLink(a, b *Router) (*Link, b for _, link := range links { if link.IsUsable() { linkCost := link.GetCost() - if link.Dst == b { + if link.DstId == b.Id { if linkCost < cost { selected = link cost = linkCost @@ -211,7 +247,8 @@ func (linkController *linkController) missingLinks(routers []*Router, pendingTim id := idgen.NewUUIDString() link := newLink(id, listener.GetProtocol(), listener.GetAddress(), linkController.initialLatency) link.Src = srcR - link.Dst = dstR + link.Dst.Store(dstR) + link.DstId = dstR.Id missingLinks = append(missingLinks, link) } } @@ -243,7 +280,7 @@ func (linkController *linkController) hasDirectedLink(a, b *Router, linkProtocol links := a.routerLinks.GetLinks() for _, link := range links { state := link.CurrentState() - if link.Src == a && link.Dst == b && state != nil && link.Protocol == linkProtocol { + if link.Src == a && link.DstId == b.Id && state != nil && link.Protocol == linkProtocol { if state.Mode == Connected || (state.Mode == Pending && state.Timestamp > pendingLimit) { return true } @@ -299,8 +336,10 @@ func (self *linkController) ValidateRouterLinks(n *Network, router *Router, cb L for _, link := range linkDetails.Links { detail := &mgmt_pb.RouterLinkDetail{ - LinkId: link.Id, - RouterState: mgmt_pb.LinkState_LinkEstablished, + LinkId: link.Id, + RouterState: mgmt_pb.LinkState_LinkEstablished, + DestRouterId: link.Dest, + Dialed: link.Dialed, } detail.DestConnected = n.ConnectedRouter(link.Dest) if _, found := linkMap[link.Id]; found { @@ -319,8 +358,8 @@ func (self *linkController) ValidateRouterLinks(n *Network, router *Router, cb L dest := "" if link.Src.Id == router.Id { related = true - dest = link.Dst.Id - } else if link.Dst.Id == router.Id { + dest = link.DstId + } else if link.DstId == router.Id { related = true dest = link.Src.Id } @@ -332,6 +371,8 @@ func (self *linkController) ValidateRouterLinks(n *Network, router *Router, cb L DestConnected: n.ConnectedRouter(dest), RouterState: mgmt_pb.LinkState_LinkUnknown, IsValid: false, + DestRouterId: dest, + Dialed: link.Src.Id == router.Id, } result.LinkDetails = append(result.LinkDetails, detail) } @@ -406,6 +447,8 @@ func (lt *linkTable) matching(f func(*Link) bool) []*Link { return links } -func (lt *linkTable) remove(link *Link) { - lt.links.Remove(link.Id) +func (lt *linkTable) remove(link *Link) bool { + return lt.links.RemoveCb(link.Id, func(key string, v *Link, exists bool) bool { + return v != nil && v.Iteration == link.Iteration + }) } diff --git a/controller/network/link_controller_test.go b/controller/network/link_controller_test.go index d0ebdeff5..2a91e91a5 100644 --- a/controller/network/link_controller_test.go +++ b/controller/network/link_controller_test.go @@ -44,10 +44,11 @@ func TestLifecycle(t *testing.T) { r0 := NewRouter("r0", "", "", 0, true) r1 := NewRouter("r1", "", "", 0, true) l0 := &Link{ - Id: "l0", - Src: r0, - Dst: r1, + Id: "l0", + Src: r0, + DstId: r1.Id, } + l0.Dst.Store(r1) linkController.add(l0) assert.True(t, linkController.has(l0)) @@ -75,11 +76,7 @@ func TestNeighbors(t *testing.T) { r0 := newRouterForTest("r0", "", nil, nil, 0, true) r1 := newRouterForTest("r1", "", nil, nil, 0, true) - l0 := &Link{ - Id: "l0", - Src: r0, - Dst: r1, - } + l0 := newTestLink("l0", r0, r1) l0.addState(newLinkState(Connected)) linkController.add(l0) @@ -88,6 +85,12 @@ func TestNeighbors(t *testing.T) { assert.Equal(t, r1, neighbors[0]) } -func newTestLink(id string, linkProtocol string) *Link { - return newLink(id, linkProtocol, "tcp:localhost:1234", 0) +func newTestLink(id string, src, dst *Router) *Link { + l := newLink(id, "tls", "tcp:localhost:1234", 0) + l.Src = src + l.DstId = dst.Id + l.Dst.Store(dst) + src.Connected.Store(true) + dst.Connected.Store(true) + return l } diff --git a/controller/network/network.go b/controller/network/network.go index 22199c7ff..2818fbc86 100644 --- a/controller/network/network.go +++ b/controller/network/network.go @@ -21,6 +21,7 @@ import ( "compress/gzip" "encoding/json" "fmt" + "github.com/openziti/foundation/v2/concurrenz" "github.com/openziti/foundation/v2/goroutines" "github.com/openziti/storage/objectz" fabricMetrics "github.com/openziti/ziti/common/metrics" @@ -315,15 +316,12 @@ func (network *Network) GetCloseNotify() <-chan struct{} { return network.closeNotify } -func (network *Network) RouterChanged(r *Router) { - network.routerChanged <- r -} - func (network *Network) ConnectedRouter(id string) bool { return network.Routers.IsConnected(id) } func (network *Network) ConnectRouter(r *Router) { + network.linkController.buildRouterLinks(r) network.Routers.markConnected(r) time.AfterFunc(250*time.Millisecond, func() { network.routerChanged <- r }) @@ -374,24 +372,32 @@ func (n *Network) ValidateLinks(filter string, cb LinkValidationCallback) (int64 return 0, nil, err } + sem := concurrenz.NewSemaphore(10) + evalF := func() { for _, router := range result.Entities { connectedRouter := n.GetConnectedRouter(router.Id) if connectedRouter != nil { - go n.linkController.ValidateRouterLinks(n, connectedRouter, cb) + sem.Acquire() + go func() { + defer sem.Release() + n.linkController.ValidateRouterLinks(n, connectedRouter, cb) + }() } else { n.linkController.reportRouterLinksError(router, errors.New("router not connected"), cb) } } } - return result.Count, evalF, nil + return int64(len(result.Entities)), evalF, nil } func (network *Network) DisconnectRouter(r *Router) { // 1: remove Links for Router for _, l := range r.routerLinks.GetLinks() { - network.linkController.remove(l) + if l.Src == r { + network.linkController.remove(l) + } network.LinkChanged(l) } // 2: remove Router @@ -404,20 +410,19 @@ func (network *Network) DisconnectRouter(r *Router) { network.routerChanged <- r } -func (network *Network) NotifyExistingLink(id, linkProtocol, dialAddress string, srcRouter *Router, dstRouterId string) { +func (network *Network) NotifyExistingLink(id string, iteration uint32, linkProtocol, dialAddress string, srcRouter *Router, dstRouterId string) { log := pfxlog.Logger(). WithField("routerId", srcRouter.Id). WithField("linkId", id). - WithField("destRouterId", dstRouterId) + WithField("destRouterId", dstRouterId). + WithField("iteration", iteration) dst := network.Routers.getConnected(dstRouterId) if dst == nil { network.NotifyLinkIdEvent(id, event.LinkFromRouterDisconnectedDest) - log.Error("destination router not connected") - return } - link, created := network.linkController.routerReportedLink(id, linkProtocol, dialAddress, srcRouter, dst) + link, created := network.linkController.routerReportedLink(id, iteration, linkProtocol, dialAddress, srcRouter, dst, dstRouterId) if created { network.NotifyLinkEvent(link, event.LinkFromRouterNew) log.Info("router reported link added") @@ -440,43 +445,16 @@ func (network *Network) LinkConnected(msg *ctrl_pb.LinkConnected) error { return errors.Errorf("no such link [l/%s]", msg.Id) } -func (network *Network) LinkFaulted(id string, dupe bool) error { - if l, found := network.linkController.get(id); found { - l.addState(newLinkState(Failed)) - if dupe { - network.NotifyLinkEvent(l, event.LinkDuplicate) - } else { - network.NotifyLinkEvent(l, event.LinkFault) - } - pfxlog.Logger().WithField("linkId", id).Info("removing failed link") - network.linkController.remove(l) - return nil - } - return errors.Errorf("no such link [l/%s]", id) -} - -func (network *Network) VerifyLinkSource(targetRouter *Router, linkId string, fingerprints []string) error { - l, found := network.linkController.get(linkId) - if !found { - return errors.Errorf("invalid link %v", linkId) - } - - if l.Dst.Id != targetRouter.Id { - return errors.Errorf("incorrect link target router. link=%v, expected router=%v, actual router=%v", l.Id, l.Dst.Id, targetRouter.Id) - } - - routerFingerprint := l.Src.Fingerprint - if routerFingerprint == nil { - return errors.Errorf("invalid source router %v for link %v, not yet enrolled", l.Src.Id, l.Id) - } - - for _, fp := range fingerprints { - if fp == *routerFingerprint { - return nil - } +func (network *Network) LinkFaulted(l *Link, dupe bool) error { + l.addState(newLinkState(Failed)) + if dupe { + network.NotifyLinkEvent(l, event.LinkDuplicate) + } else { + network.NotifyLinkEvent(l, event.LinkFault) } - - return errors.Errorf("could not verify fingerprint for router %v on link %v", l.Src.Id, l.Id) + pfxlog.Logger().WithField("linkId", l.Id).Info("removing failed link") + network.linkController.remove(l) + return nil } func (network *Network) VerifyRouter(routerId string, fingerprints []string) error { @@ -1001,11 +979,18 @@ func (network *Network) RemoveLink(linkId string) { log := pfxlog.Logger().WithField("linkId", linkId) link, _ := network.linkController.get(linkId) + var iteration uint32 var routerList []*Router if link != nil { - routerList = []*Router{link.Src, link.Dst} - log = log.WithField("srcRouterId", link.Src.Id).WithField("dstRouterId", link.Dst.Id) + iteration = link.Iteration + routerList = []*Router{link.Src} + if dst := link.GetDest(); dst != nil { + routerList = append(routerList, dst) + } + log = log.WithField("srcRouterId", link.Src.Id). + WithField("dstRouterId", link.DstId). + WithField("iteration", iteration) log.Info("deleting known link") } else { routerList = network.AllConnectedRouters() @@ -1013,7 +998,12 @@ func (network *Network) RemoveLink(linkId string) { } for _, router := range routerList { - fault := &ctrl_pb.Fault{Subject: ctrl_pb.FaultSubject_LinkFault, Id: linkId} + fault := &ctrl_pb.Fault{ + Subject: ctrl_pb.FaultSubject_LinkFault, + Id: linkId, + Iteration: iteration, + } + if ctrl := router.Control; ctrl != nil { if err := protobufs.MarshalTyped(fault).WithTimeout(15 * time.Second).Send(ctrl); err != nil { log.WithField("faultDestRouterId", router.Id).WithError(err). @@ -1158,7 +1148,7 @@ func (network *Network) AcceptMetricsMsg(metrics *metrics_pb.MetricsMessage) { if found { if link.Src.Id == router.Id { link.SetSrcLatency(latencyCost) // latency is in nanoseconds - } else if link.Dst.Id == router.Id { + } else if link.DstId == router.Id { link.SetDstLatency(latencyCost) // latency is in nanoseconds } else { log.Warnf("link not for router") diff --git a/controller/network/options.go b/controller/network/options.go index c0f3334ab..791d4f1b1 100644 --- a/controller/network/options.go +++ b/controller/network/options.go @@ -27,7 +27,7 @@ import ( const ( DefaultOptionsCreateCircuitRetries = 2 DefaultOptionsCycleSeconds = 60 - DefaultOptionsEnableLegacyLinkMgmt = true + DefaultOptionsEnableLegacyLinkMgmt = false DefaultOptionsInitialLinkLatency = 65 * time.Second DefaultOptionsPendingLinkTimeout = 10 * time.Second DefaultOptionsMetricsReportInterval = time.Minute diff --git a/controller/network/path_test.go b/controller/network/path_test.go index 37f9dc555..678428c22 100644 --- a/controller/network/path_test.go +++ b/controller/network/path_test.go @@ -23,10 +23,10 @@ import ( "github.com/stretchr/testify/require" "github.com/openziti/channel/v2" - "github.com/openziti/ziti/controller/db" - "github.com/openziti/ziti/controller/models" "github.com/openziti/transport/v2" "github.com/openziti/transport/v2/tcp" + "github.com/openziti/ziti/controller/db" + "github.com/openziti/ziti/controller/models" "github.com/stretchr/testify/assert" ) @@ -50,9 +50,7 @@ func TestSimplePath2(t *testing.T) { r1 := newRouterForTest("r1", "", transportAddr, nil, 0, false) network.Routers.markConnected(r1) - l0 := newTestLink("l0", "tls") - l0.Src = r0 - l0.Dst = r1 + l0 := newTestLink("l0", r0, r1) l0.addState(newLinkState(Connected)) network.linkController.add(l0) @@ -116,15 +114,11 @@ func TestTransitPath2(t *testing.T) { r2 := newRouterForTest("r2", "", transportAddr, nil, 0, false) network.Routers.markConnected(r2) - l0 := newTestLink("l0", "tls") - l0.Src = r0 - l0.Dst = r1 + l0 := newTestLink("l0", r0, r1) l0.addState(newLinkState(Connected)) network.linkController.add(l0) - l1 := newTestLink("l1", "tls") - l1.Src = r1 - l1.Dst = r2 + l1 := newTestLink("l1", r1, r2) l1.addState(newLinkState(Connected)) network.linkController.add(l1) @@ -220,39 +214,31 @@ func TestShortestPath(t *testing.T) { r3 := newRouterForTest("r3", "", transportAddr, nil, 4, false) network.Routers.markConnected(r3) - link := newTestLink("l0", "tls") + link := newTestLink("l0", r0, r1) link.SetStaticCost(2) link.SetDstLatency(10 * 1_000_000) link.SetSrcLatency(11 * 1_000_000) - link.Src = r0 - link.Dst = r1 link.addState(newLinkState(Connected)) network.linkController.add(link) - link = newTestLink("l1", "tls") + link = newTestLink("l1", r0, r2) link.SetStaticCost(5) link.SetDstLatency(15 * 1_000_000) link.SetSrcLatency(16 * 1_000_000) - link.Src = r0 - link.Dst = r2 link.addState(newLinkState(Connected)) network.linkController.add(link) - link = newTestLink("l2", "tls") + link = newTestLink("l2", r1, r3) link.SetStaticCost(9) link.SetDstLatency(20 * 1_000_000) link.SetSrcLatency(21 * 1_000_000) - link.Src = r1 - link.Dst = r3 link.addState(newLinkState(Connected)) network.linkController.add(link) - link = newTestLink("l3", "tls") + link = newTestLink("l3", r2, r3) link.SetStaticCost(13) link.SetDstLatency(25 * 1_000_000) link.SetSrcLatency(26 * 1_000_000) - link.Src = r2 - link.Dst = r3 link.addState(newLinkState(Connected)) network.linkController.add(link) @@ -296,39 +282,31 @@ func TestShortestPathWithUntraversableRouter(t *testing.T) { r3 := newRouterForTest("r3", "", transportAddr, nil, 4, false) network.Routers.markConnected(r3) - link := newTestLink("l0", "tls") + link := newTestLink("l0", r0, r1) link.SetStaticCost(2) link.SetDstLatency(10 * 1_000_000) link.SetSrcLatency(11 * 1_000_000) - link.Src = r0 - link.Dst = r1 link.addState(newLinkState(Connected)) network.linkController.add(link) - link = newTestLink("l1", "tls") + link = newTestLink("l1", r0, r2) link.SetStaticCost(5) link.SetDstLatency(15 * 1_000_000) link.SetSrcLatency(16 * 1_000_000) - link.Src = r0 - link.Dst = r2 link.addState(newLinkState(Connected)) network.linkController.add(link) - link = newTestLink("l2", "tls") + link = newTestLink("l2", r1, r3) link.SetStaticCost(9) link.SetDstLatency(20 * 1_000_000) link.SetSrcLatency(21 * 1_000_000) - link.Src = r1 - link.Dst = r3 link.addState(newLinkState(Connected)) network.linkController.add(link) - link = newTestLink("l3", "tls") + link = newTestLink("l3", r2, r3) link.SetStaticCost(13) link.SetDstLatency(25 * 1_000_000) link.SetSrcLatency(26 * 1_000_000) - link.Src = r2 - link.Dst = r3 link.addState(newLinkState(Connected)) network.linkController.add(link) @@ -366,12 +344,10 @@ func TestShortestPathWithOnlyUntraversableRouter(t *testing.T) { r1 := newRouterForTest("r1", "", transportAddr, nil, 2, true) network.Routers.markConnected(r1) - link := newTestLink("l0", "tls") + link := newTestLink("l0", r0, r1) link.SetStaticCost(2) link.SetDstLatency(10 * 1_000_000) link.SetSrcLatency(11 * 1_000_000) - link.Src = r0 - link.Dst = r1 link.addState(newLinkState(Connected)) network.linkController.add(link) @@ -408,12 +384,10 @@ func TestShortestPathWithUntraversableEdgeRouters(t *testing.T) { r1 := newRouterForTest("r1", "", transportAddr, nil, 2, true) network.Routers.markConnected(r1) - link := newTestLink("l0", "tls") + link := newTestLink("l0", r0, r1) link.SetStaticCost(3) link.SetDstLatency(10 * 1_000_000) link.SetSrcLatency(11 * 1_000_000) - link.Src = r0 - link.Dst = r1 link.addState(newLinkState(Connected)) network.linkController.add(link) @@ -453,21 +427,17 @@ func TestShortestPathWithUntraversableEdgeRoutersAndTraversableMiddle(t *testing r2 := newRouterForTest("r2", "", transportAddr, nil, 3, true) network.Routers.markConnected(r2) - link := newTestLink("l0", "tls") + link := newTestLink("l0", r0, r1) link.SetStaticCost(2) link.SetDstLatency(10 * 1_000_000) link.SetSrcLatency(11 * 1_000_000) - link.Src = r0 - link.Dst = r1 link.addState(newLinkState(Connected)) network.linkController.add(link) - link = newTestLink("l1", "tls") + link = newTestLink("l1", r1, r2) link.SetStaticCost(3) link.SetDstLatency(12 * 1_000_000) link.SetSrcLatency(15 * 1_000_000) - link.Src = r1 - link.Dst = r2 link.addState(newLinkState(Connected)) network.linkController.add(link) @@ -509,21 +479,17 @@ func TestShortestPathWithUntraversableEdgeRoutersAndUntraversableMiddle(t *testi r2 := newRouterForTest("r2", "", transportAddr, nil, 2, true) network.Routers.markConnected(r2) - link := newTestLink("l0", "tls") + link := newTestLink("l0", r0, r1) link.SetStaticCost(2) link.SetDstLatency(10 * 1_000_000) link.SetSrcLatency(11 * 1_000_000) - link.Src = r0 - link.Dst = r1 link.addState(newLinkState(Connected)) network.linkController.add(link) - link = newTestLink("l2", "tls") + link = newTestLink("l2", r1, r2) link.SetStaticCost(2) link.SetDstLatency(10 * 1_000_000) link.SetSrcLatency(11 * 1_000_000) - link.Src = r1 - link.Dst = r2 link.addState(newLinkState(Connected)) network.linkController.add(link) @@ -649,9 +615,7 @@ func TestMinRouterCost(t *testing.T) { } func newPathTestLink(network *Network, id string, srcR, destR *Router) *Link { - l := newTestLink(id, "tls") - l.Src = srcR - l.Dst = destR + l := newTestLink(id, srcR, destR) l.SrcLatency = 0 l.DstLatency = 0 l.recalculateCost() diff --git a/controller/network/route_perf_test.go b/controller/network/route_perf_test.go index b60ba4fc1..c28daf0ef 100644 --- a/controller/network/route_perf_test.go +++ b/controller/network/route_perf_test.go @@ -58,12 +58,10 @@ func TestShortestPathAgainstEstablished(t *testing.T) { addLink := func(srcRouter, dstRouter *Router) { if srcRouter != dstRouter { - link := newTestLink(fmt.Sprintf("link-%04d", linkIdx), "tls") + link := newTestLink(fmt.Sprintf("link-%04d", linkIdx), srcRouter, dstRouter) link.SetStaticCost(int32(nextCost())) link.SetDstLatency(nextCost() * 100_000) link.SetSrcLatency(nextCost() * 100_000) - link.Src = srcRouter - link.Dst = dstRouter link.addState(newLinkState(Connected)) network.linkController.add(link) linkIdx++ @@ -184,12 +182,10 @@ func BenchmarkShortestPathPerfWithRouterChanges(b *testing.B) { addLink := func(srcRouter, dstRouter *Router) { if srcRouter != dstRouter { - link := newTestLink(fmt.Sprintf("link-%04d", linkIdx), "tls") + link := newTestLink(fmt.Sprintf("link-%04d", linkIdx), srcRouter, dstRouter) link.SetStaticCost(int32(nextCost())) link.SetDstLatency(nextCost() * 100_000) link.SetSrcLatency(nextCost() * 100_000) - link.Src = srcRouter - link.Dst = dstRouter link.addState(newLinkState(Connected)) network.linkController.add(link) linkIdx++ @@ -278,12 +274,10 @@ func BenchmarkShortestPathPerf(b *testing.B) { addLink := func(srcRouter, dstRouter *Router) { if srcRouter != dstRouter { - link := newTestLink(fmt.Sprintf("link-%04d", linkIdx), "tls") + link := newTestLink(fmt.Sprintf("link-%04d", linkIdx), srcRouter, dstRouter) link.SetStaticCost(int32(nextCost())) link.SetDstLatency(nextCost() * 100_000) link.SetSrcLatency(nextCost() * 100_000) - link.Src = srcRouter - link.Dst = dstRouter link.addState(newLinkState(Connected)) network.linkController.add(link) linkIdx++ @@ -352,12 +346,10 @@ func BenchmarkMoreRealisticShortestPathPerf(b *testing.B) { addLink := func(srcRouter, dstRouter *Router) { if srcRouter != dstRouter { - link := newTestLink(fmt.Sprintf("link-%04d", linkIdx), "tls") + link := newTestLink(fmt.Sprintf("link-%04d", linkIdx), srcRouter, dstRouter) link.SetStaticCost(int32(nextCost())) link.SetDstLatency(nextCost() * 100_000) link.SetSrcLatency(nextCost() * 100_000) - link.Src = srcRouter - link.Dst = dstRouter link.addState(newLinkState(Connected)) network.linkController.add(link) linkIdx++ diff --git a/controller/network/router.go b/controller/network/router.go index ad8af5d46..c086591fa 100644 --- a/controller/network/router.go +++ b/controller/network/router.go @@ -17,14 +17,14 @@ package network import ( + "github.com/openziti/foundation/v2/genext" + "github.com/openziti/foundation/v2/versions" + "github.com/openziti/ziti/common/pb/cmd_pb" + "github.com/openziti/ziti/common/pb/ctrl_pb" "github.com/openziti/ziti/controller/change" "github.com/openziti/ziti/controller/command" "github.com/openziti/ziti/controller/fields" "github.com/openziti/ziti/controller/xt" - "github.com/openziti/ziti/common/pb/cmd_pb" - "github.com/openziti/ziti/common/pb/ctrl_pb" - "github.com/openziti/foundation/v2/genext" - "github.com/openziti/foundation/v2/versions" "google.golang.org/protobuf/proto" "reflect" "sync" @@ -33,9 +33,9 @@ import ( "github.com/michaelquigley/pfxlog" "github.com/openziti/channel/v2" + "github.com/openziti/storage/boltz" "github.com/openziti/ziti/controller/db" "github.com/openziti/ziti/controller/models" - "github.com/openziti/storage/boltz" cmap "github.com/orcaman/concurrent-map/v2" "github.com/pkg/errors" "go.etcd.io/bbolt" @@ -473,7 +473,7 @@ func (self *RouterLinks) GetLinksByRouter() map[string][]*Link { return result.(map[string][]*Link) } -func (self *RouterLinks) Add(link *Link, other *Router) { +func (self *RouterLinks) Add(link *Link, otherRouterId string) { self.Lock() defer self.Unlock() links := self.GetLinks() @@ -487,13 +487,13 @@ func (self *RouterLinks) Add(link *Link, other *Router) { for k, v := range byRouter { newLinksByRouter[k] = v } - forRouterList := newLinksByRouter[other.Id] + forRouterList := newLinksByRouter[otherRouterId] newForRouterList := append([]*Link{link}, forRouterList...) - newLinksByRouter[other.Id] = newForRouterList + newLinksByRouter[otherRouterId] = newForRouterList self.linkByRouter.Store(newLinksByRouter) } -func (self *RouterLinks) Remove(link *Link, other *Router) { +func (self *RouterLinks) Remove(link *Link, otherRouterId string) { self.Lock() defer self.Unlock() links := self.GetLinks() @@ -510,7 +510,7 @@ func (self *RouterLinks) Remove(link *Link, other *Router) { for k, v := range byRouter { newLinksByRouter[k] = v } - forRouterList := newLinksByRouter[other.Id] + forRouterList := newLinksByRouter[otherRouterId] var newForRouterList []*Link for _, l := range forRouterList { if l != link { @@ -518,9 +518,9 @@ func (self *RouterLinks) Remove(link *Link, other *Router) { } } if len(newForRouterList) == 0 { - delete(newLinksByRouter, other.Id) + delete(newLinksByRouter, otherRouterId) } else { - newLinksByRouter[other.Id] = newForRouterList + newLinksByRouter[otherRouterId] = newForRouterList } self.linkByRouter.Store(newLinksByRouter) diff --git a/controller/rest_model/link_detail.go b/controller/rest_model/link_detail.go index 8b75648c7..0baac243a 100644 --- a/controller/rest_model/link_detail.go +++ b/controller/rest_model/link_detail.go @@ -63,6 +63,10 @@ type LinkDetail struct { // Required: true ID *string `json:"id"` + // iteration + // Required: true + Iteration *int64 `json:"iteration"` + // protocol // Required: true Protocol *string `json:"protocol"` @@ -108,6 +112,10 @@ func (m *LinkDetail) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateIteration(formats); err != nil { + res = append(res, err) + } + if err := m.validateProtocol(formats); err != nil { res = append(res, err) } @@ -190,6 +198,15 @@ func (m *LinkDetail) validateID(formats strfmt.Registry) error { return nil } +func (m *LinkDetail) validateIteration(formats strfmt.Registry) error { + + if err := validate.Required("iteration", "body", m.Iteration); err != nil { + return err + } + + return nil +} + func (m *LinkDetail) validateProtocol(formats strfmt.Registry) error { if err := validate.Required("protocol", "body", m.Protocol); err != nil { diff --git a/controller/rest_server/embedded_spec.go b/controller/rest_server/embedded_spec.go index 23bddce72..9fad1fb08 100644 --- a/controller/rest_server/embedded_spec.go +++ b/controller/rest_server/embedded_spec.go @@ -1729,7 +1729,8 @@ func init() { "sourceLatency", "destLatency", "cost", - "down" + "down", + "iteration" ], "properties": { "cost": { @@ -1747,6 +1748,9 @@ func init() { "id": { "type": "string" }, + "iteration": { + "type": "integer" + }, "protocol": { "type": "string" }, @@ -7320,7 +7324,8 @@ func init() { "sourceLatency", "destLatency", "cost", - "down" + "down", + "iteration" ], "properties": { "cost": { @@ -7338,6 +7343,9 @@ func init() { "id": { "type": "string" }, + "iteration": { + "type": "integer" + }, "protocol": { "type": "string" }, diff --git a/controller/specs/swagger.yml b/controller/specs/swagger.yml index 86b7cf3b7..53ef15c41 100644 --- a/controller/specs/swagger.yml +++ b/controller/specs/swagger.yml @@ -1811,6 +1811,7 @@ definitions: - destLatency - cost - down + - iteration properties: id: type: string @@ -1832,6 +1833,8 @@ definitions: type: integer cost: type: integer + iteration: + type: integer linkPatch: type: object properties: diff --git a/go.mod b/go.mod index 220751b7f..4291a68c6 100644 --- a/go.mod +++ b/go.mod @@ -47,17 +47,17 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/natefinch/lumberjack v2.0.0+incompatible github.com/openziti/agent v1.0.16 - github.com/openziti/channel/v2 v2.0.113 - github.com/openziti/edge-api v0.26.7 - github.com/openziti/foundation/v2 v2.0.35 - github.com/openziti/identity v1.0.68 + github.com/openziti/channel/v2 v2.0.116 + github.com/openziti/edge-api v0.26.8 + github.com/openziti/foundation/v2 v2.0.36 + github.com/openziti/identity v1.0.69 github.com/openziti/jwks v1.0.3 - github.com/openziti/metrics v1.2.41 - github.com/openziti/runzmd v1.0.36 - github.com/openziti/sdk-golang v0.22.6 - github.com/openziti/secretstream v0.1.15 - github.com/openziti/storage v0.2.27 - github.com/openziti/transport/v2 v2.0.119 + github.com/openziti/metrics v1.2.43 + github.com/openziti/runzmd v1.0.37 + github.com/openziti/sdk-golang v0.22.17 + github.com/openziti/secretstream v0.1.16 + github.com/openziti/storage v0.2.28 + github.com/openziti/transport/v2 v2.0.121 github.com/openziti/x509-claims v1.0.3 github.com/openziti/xweb/v2 v2.1.0 github.com/openziti/ziti-db-explorer v1.1.3 @@ -78,8 +78,8 @@ require ( github.com/zitadel/oidc/v2 v2.12.0 go.etcd.io/bbolt v1.3.8 go4.org v0.0.0-20180809161055-417644f6feb5 - golang.org/x/crypto v0.17.0 - golang.org/x/net v0.19.0 + golang.org/x/crypto v0.18.0 + golang.org/x/net v0.20.0 golang.org/x/sync v0.5.0 golang.org/x/sys v0.16.0 golang.org/x/text v0.14.0 @@ -115,13 +115,13 @@ require ( github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect - github.com/go-openapi/analysis v0.22.1 // indirect + github.com/go-openapi/analysis v0.22.2 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 // indirect - github.com/gorilla/schema v1.2.1 // indirect - github.com/gorilla/securecookie v1.1.2 // indirect + github.com/gorilla/schema v1.2.0 // indirect + github.com/gorilla/securecookie v1.1.1 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-msgpack v0.5.5 // indirect github.com/hashicorp/go-msgpack/v2 v2.1.1 // indirect @@ -166,8 +166,8 @@ require ( github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/tklauser/go-sysconf v0.3.13 // indirect - github.com/tklauser/numcpus v0.7.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect @@ -180,10 +180,10 @@ require ( go.opentelemetry.io/otel/trace v1.21.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect - golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect + golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/image v0.13.0 // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/oauth2 v0.15.0 // indirect + golang.org/x/oauth2 v0.16.0 // indirect golang.org/x/term v0.16.0 // indirect golang.org/x/tools v0.16.0 // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/go.sum b/go.sum index f95457cdc..c0c66fee2 100644 --- a/go.sum +++ b/go.sum @@ -216,8 +216,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -github.com/go-openapi/analysis v0.22.1 h1:nBWSKtx/OQr6FADwy0AYDZFdT05Abv5eYWECByHEQMg= -github.com/go-openapi/analysis v0.22.1/go.mod h1:acDnkkCI2QxIo8sSIPgmp1wUlRohV7vfGtAIVae73b0= +github.com/go-openapi/analysis v0.22.2 h1:ZBmNoP2h5omLKr/srIC9bfqrUGzT6g6gNv03HE9Vpj0= +github.com/go-openapi/analysis v0.22.2/go.mod h1:pDF4UbZsQTo/oNuRfAWWd4dAh4yuYf//LYorPTjrpvo= github.com/go-openapi/errors v0.21.0 h1:FhChC/duCnfoLj1gZ0BgaBmzhJC2SL/sJr8a2vAobSY= github.com/go-openapi/errors v0.21.0/go.mod h1:jxNTMUxRCKj65yb/okJGEtahVd7uvWnuWfj53bse4ho= github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= @@ -306,8 +306,6 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -337,10 +335,10 @@ github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyE github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/schema v1.2.1 h1:tjDxcmdb+siIqkTNoV+qRH2mjYdr2hHe5MKXbp61ziM= -github.com/gorilla/schema v1.2.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= -github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= -github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= +github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc= +github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU= +github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= @@ -567,30 +565,30 @@ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYr github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openziti/agent v1.0.16 h1:9Saji+8hFE1NpzP2XzDhsVJbCrDlhixoLHfOpFt5Z+U= github.com/openziti/agent v1.0.16/go.mod h1:zfm53+PVWoGFzjGGgQdKby5749G6VRYHe+eQJmoVKy4= -github.com/openziti/channel/v2 v2.0.113 h1:J7GdiwusrwpHtbQKAgQErRe4RJdeqTUQhIZNgsZpDn4= -github.com/openziti/channel/v2 v2.0.113/go.mod h1:1cVOKm52klHza4WxRgcT4Ec/NlFrGwjXPZt/V7bSE+o= +github.com/openziti/channel/v2 v2.0.116 h1:VUxJ3rICTQz9fmSz6tbssC2tzXafL1MAY6yvgHfSUHI= +github.com/openziti/channel/v2 v2.0.116/go.mod h1:RADBBOkbwpFMmbznU3bZmUsBB646seqZnQ7GPI6Chjg= github.com/openziti/dilithium v0.3.3 h1:PLgQ6PMNLSTzCFbX/h98cmudgz/cU6TmjdSv5NAPD8k= github.com/openziti/dilithium v0.3.3/go.mod h1:vsCjI2AU/hon9e+dLhUFbCNGesJDj2ASgkySOcpmvjo= -github.com/openziti/edge-api v0.26.7 h1:dHLH7+O+Yp3HPmhgAbvq8z93EcZDypiSOHm/PVVUCoc= -github.com/openziti/edge-api v0.26.7/go.mod h1:yKQYyc3zhHRM7Y2BRd5R7gT9zelh46julW4chjv2W9I= -github.com/openziti/foundation/v2 v2.0.35 h1:4VaMwZ2kAy6jwBYeQIBN2m8rcGroTDX4A2Jp7NAKb6M= -github.com/openziti/foundation/v2 v2.0.35/go.mod h1:Xnb3IxP1e1UcgLggqSunEpCjH3iHozkPi9Bd9GESbwo= -github.com/openziti/identity v1.0.68 h1:SaFr7BeFQBoWQDiT28vUb8D9w7v6lIAK6/9RkwmV0OU= -github.com/openziti/identity v1.0.68/go.mod h1:HbOu3TQ032v8xE6xZWjO51azF4fUxRLjO/l/oGqJwUI= +github.com/openziti/edge-api v0.26.8 h1:W1iHwVrb4hVKXWhfN8g/dl1d0RGdus6nOYbhM5ixOEg= +github.com/openziti/edge-api v0.26.8/go.mod h1:Tm2Qn1BC0zF+F261Y8FTyPtS/UkeUtUBYoT6ueCjVbA= +github.com/openziti/foundation/v2 v2.0.36 h1:ogEIvsWur8/9mUzf9NOB4hRUyx372Uy6AmnHRcurIkY= +github.com/openziti/foundation/v2 v2.0.36/go.mod h1:MdK2oAJSwo7iCfvVdG16ZGz47qP7nG97ovnqEdXW2kQ= +github.com/openziti/identity v1.0.69 h1:wNgQomnv8ar2S1wge9jQK1jpqE2virOKKG8GyfTiHMQ= +github.com/openziti/identity v1.0.69/go.mod h1:+7hQNAG5nUUdz0165OubWpMHkP/ZVJB3nv9HUXXi9H8= github.com/openziti/jwks v1.0.3 h1:hf8wkb+Cg4nH/HM0KROFd7u+C3DkRVcFZJ7tDV+4icc= github.com/openziti/jwks v1.0.3/go.mod h1:t4xxq8vlXGsPn29kiQVnZBBDDnEoOFqtJoHibkJunQQ= -github.com/openziti/metrics v1.2.41 h1:JShcFb6qJPA2cMiWQLtcSXiJjsrhEWpH+aVcjT/Mcbs= -github.com/openziti/metrics v1.2.41/go.mod h1:L9h0NrliMA3+p7+ascKgvx28qoKHymN9l+CMA+Q+sZc= -github.com/openziti/runzmd v1.0.36 h1:HOqTZFzTTFu52qmCAQfFvKDmCSl8ZqP1PQQ0UnJIA4E= -github.com/openziti/runzmd v1.0.36/go.mod h1:jYqummjskmFh63htJFF2SrUuvxNQifqd5REUhYVaY/A= -github.com/openziti/sdk-golang v0.22.6 h1:AG0FNnh3QHTmqgL7Igl+ib2V65h0I2GskZ4Xi97eOo8= -github.com/openziti/sdk-golang v0.22.6/go.mod h1:eq0Ww3cX8SVUyhAVGlZSZPIGBrMEnUioVBRME/IZ7rU= -github.com/openziti/secretstream v0.1.15 h1:bGoPlT5zmZ+BiLKFMlaARG3gfiUzuhX/kmK6OInaghU= -github.com/openziti/secretstream v0.1.15/go.mod h1:LyghB5JOlgvFASkLYPiBgjj5rcFXKiLD4qwHYRfBxnU= -github.com/openziti/storage v0.2.27 h1:WdFD0KxXZxSoWOaojdi5r1LO0BTvn4x/7wwdwhRPssc= -github.com/openziti/storage v0.2.27/go.mod h1:p/04So5E3NT2jsGew0AS4hYTfP5srti3VytOjlVcx0M= -github.com/openziti/transport/v2 v2.0.119 h1:KOgHU+9EZUVPvv8ncifqHmNEcFUHbJHigo3jyPvWnOc= -github.com/openziti/transport/v2 v2.0.119/go.mod h1:H2IIBP6ed9isE/eJHGXtAZL0d73ApYOpLG9sSvutNNI= +github.com/openziti/metrics v1.2.43 h1:DSrmpLhoA45DlLVNdKOn2lBfCM0/r6wKz+3SDXe8X7Y= +github.com/openziti/metrics v1.2.43/go.mod h1:+RY4avT60Vbxb9wyfvRD0msrARyYCB5+heb8VIZzCm8= +github.com/openziti/runzmd v1.0.37 h1:qj2r9z4t7OAdmIXMdGbP9Su6TqA0bLdD2RMjJ71LRS0= +github.com/openziti/runzmd v1.0.37/go.mod h1:eKhqJsGoLeDHex/o5Mw6TcNJxlVljafSVm7ZU+bX5G8= +github.com/openziti/sdk-golang v0.22.17 h1:taywYpWpWBtZUj6KewMScYXgPe8TWz2nWNl96/y/IZ4= +github.com/openziti/sdk-golang v0.22.17/go.mod h1:t0sT5N1Q/LdAd54Dxz274sQ9vJo8/B5Q0jn+VZ9vFuw= +github.com/openziti/secretstream v0.1.16 h1:tVanF7OpJL1MJ1gvWaRlR2i+kAbrGsxr3q6EXFOS08U= +github.com/openziti/secretstream v0.1.16/go.mod h1:bvjGBUW/0e5MzD5S3FW3rhGASRNWAi+kTkTENZ9qRDE= +github.com/openziti/storage v0.2.28 h1:qHnsSF4RgQpT23hOXlwkAvJ0gO5PLmvTqyBy13dm3Rc= +github.com/openziti/storage v0.2.28/go.mod h1:ahdvsmmdQWFsZXeExvXeA8MHUXPLrwuDFBJDTztLY5E= +github.com/openziti/transport/v2 v2.0.121 h1:9WB1/9YMFed2UuefqZq+odUYYkoFOr+8aBIAZEC1MNE= +github.com/openziti/transport/v2 v2.0.121/go.mod h1:hS7TzoyTIwm4lVEsGyjQkoEg+vA+6dAOR8S4FZmWIj4= github.com/openziti/x509-claims v1.0.3 h1:HNdQ8Nf1agB3lBs1gahcO6zfkeS4S5xoQ2/PkY4HRX0= github.com/openziti/x509-claims v1.0.3/go.mod h1:Z0WIpBm6c4ecrpRKrou6Gk2wrLWxJO/+tuUwKh8VewE= github.com/openziti/xweb/v2 v2.1.0 h1:Xhh3C2pZkq/Prr65V+SfFSibLDYteoc4f62KQCcTZF4= @@ -767,12 +765,10 @@ github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSW github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 h1:3SNcvBmEPE1YlB1JpVZouslJpI3GBNoiqW7+wb0Rz7w= github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= -github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4= -github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= -github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4= -github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= @@ -867,8 +863,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -879,8 +875,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM= -golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -968,8 +964,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -984,8 +980,8 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/router/accepter.go b/router/accepter.go index ffbc962ee..288f381d7 100644 --- a/router/accepter.go +++ b/router/accepter.go @@ -16,7 +16,10 @@ func (self *xlinkAccepter) Accept(xlink xlink.Xlink) error { if err := self.forwarder.RegisterLink(xlink); err != nil { return err } - logrus.Infof("accepted new link [l/%s]", xlink.Id()) + logrus.WithField("linkId", xlink.Id()). + WithField("destId", xlink.DestinationId()). + WithField("iteration", xlink.Iteration()). + Info("accepted new link") return nil } diff --git a/router/config.go b/router/config.go index 9e9f6b6d8..f338f130b 100644 --- a/router/config.go +++ b/router/config.go @@ -19,6 +19,7 @@ package router import ( "bytes" "fmt" + "github.com/openziti/transport/v2/tls" "github.com/openziti/ziti/router/env" "io" "os" @@ -27,13 +28,13 @@ import ( "github.com/michaelquigley/pfxlog" "github.com/openziti/channel/v2" + "github.com/openziti/foundation/v2/concurrenz" + "github.com/openziti/identity" + "github.com/openziti/transport/v2" "github.com/openziti/ziti/common/config" "github.com/openziti/ziti/common/pb/ctrl_pb" "github.com/openziti/ziti/router/forwarder" "github.com/openziti/ziti/router/xgress" - "github.com/openziti/foundation/v2/concurrenz" - "github.com/openziti/identity" - "github.com/openziti/transport/v2" "github.com/pkg/errors" "github.com/spf13/pflag" "gopkg.in/yaml.v2" @@ -743,6 +744,18 @@ func LoadConfig(path string) (*Config, error) { } } + if value, found := cfgmap["tls"]; found { + if tlsMap, ok := value.(map[interface{}]interface{}); ok { + if value, found := tlsMap["handshakeTimeout"]; found { + if val, err := time.ParseDuration(fmt.Sprintf("%v", value)); err == nil { + tls.SetSharedListenerHandshakeTimeout(val) + } else { + return nil, errors.Wrapf(err, "failed to parse tls.handshakeTimeout value '%v", value) + } + } + } + } + return cfg, nil } diff --git a/router/forwarder/options.go b/router/forwarder/options.go index f0011169c..05521b1cb 100644 --- a/router/forwarder/options.go +++ b/router/forwarder/options.go @@ -44,7 +44,7 @@ const ( DefaultRateLimiterQueueLength = 5000 MinRateLimiterWorkerQueueLength = 1 MaxRateLimiterWorkerQueueLength = 50000 - DefaultRateLimiterWorkerCount = 5 + DefaultRateLimiterWorkerCount = 15 MinRateLimiterWorkerCount = 1 MaxRateLimiterWorkerCount = 10000 diff --git a/router/handler_ctrl/fault.go b/router/handler_ctrl/fault.go index f124b181d..16315b1b1 100644 --- a/router/handler_ctrl/fault.go +++ b/router/handler_ctrl/fault.go @@ -56,6 +56,12 @@ func (self *faultHandler) handleFault(_ *channel.Message, ch channel.Channel, fa linkId := fault.Id log = log.WithField("linkId", linkId) if link, _ := self.xlinkRegistry.GetLinkById(linkId); link != nil { + if fault.Iteration > 0 && fault.Iteration < link.Iteration() { + log.WithField("fault.iteration", fault.Iteration). + WithField("link.iteration", link.Iteration()). + Info("link fault reported, but fault iteration < link iteration, ignoring") + return + } log.Info("link fault reported, closing") if err := link.CloseNotified(); err != nil { log.WithError(err).Error("failure closing link") diff --git a/router/handler_link/bind.go b/router/handler_link/bind.go index 236a5dfa0..be5937291 100644 --- a/router/handler_link/bind.go +++ b/router/handler_link/bind.go @@ -67,11 +67,9 @@ func (self *bindHandler) BindChannel(binding channel.Binding) error { "routerVersion": self.xlink.DestVersion(), }) - closeNotify := make(chan struct{}) - binding.GetChannel().SetLogicalName("l/" + self.xlink.Id()) binding.SetUserData(self.xlink.Id()) - binding.AddCloseHandler(newCloseHandler(self.xlink, self.ctrl, self.forwarder, closeNotify, self.xlinkRegistry)) + binding.AddCloseHandler(newCloseHandler(self.xlink, self.forwarder, self.xlinkRegistry)) binding.AddErrorHandler(newErrorHandler(self.xlink, self.ctrl)) binding.AddTypedReceiveHandler(newPayloadHandler(self.xlink, self.forwarder)) binding.AddTypedReceiveHandler(newAckHandler(self.xlink, self.forwarder)) diff --git a/router/handler_link/close.go b/router/handler_link/close.go index 8803fed9d..66ce5e443 100644 --- a/router/handler_link/close.go +++ b/router/handler_link/close.go @@ -19,38 +19,30 @@ package handler_link import ( "github.com/michaelquigley/pfxlog" "github.com/openziti/channel/v2" - "github.com/openziti/channel/v2/protobufs" - "github.com/openziti/ziti/common/pb/ctrl_pb" - "github.com/openziti/ziti/router/env" "github.com/openziti/ziti/router/forwarder" "github.com/openziti/ziti/router/xlink" - "sync/atomic" ) type closeHandler struct { link xlink.Xlink - ctrl env.NetworkControllers forwarder *forwarder.Forwarder - closeNotify chan struct{} - closed atomic.Bool xlinkRegistry xlink.Registry } -func newCloseHandler(link xlink.Xlink, ctrl env.NetworkControllers, forwarder *forwarder.Forwarder, closeNotify chan struct{}, registry xlink.Registry) *closeHandler { +func newCloseHandler(link xlink.Xlink, forwarder *forwarder.Forwarder, registry xlink.Registry) *closeHandler { return &closeHandler{ link: link, - ctrl: ctrl, forwarder: forwarder, - closeNotify: closeNotify, xlinkRegistry: registry, } } func (self *closeHandler) HandleClose(ch channel.Channel) { - if self.closed.CompareAndSwap(false, true) { + self.link.CloseOnce(func() { log := pfxlog.ContextLogger(ch.Label()). WithField("linkId", self.link.Id()). - WithField("routerId", self.link.DestinationId()) + WithField("routerId", self.link.DestinationId()). + WithField("iteration", self.link.Iteration()) self.forwarder.UnregisterLink(self.link) @@ -62,18 +54,5 @@ func (self *closeHandler) HandleClose(ch channel.Channel) { }() log.Info("link closed") - - self.link.HandleCloseNotification(func() { - self.ctrl.ForEach(func(controllerId string, ch channel.Channel) { - fault := &ctrl_pb.Fault{Subject: ctrl_pb.FaultSubject_LinkFault, Id: self.link.Id()} - if err := protobufs.MarshalTyped(fault).Send(ch); err == nil { - log.WithField("ctrlId", controllerId).Debug("transmitted link fault") - } else { - log.WithField("ctrlId", controllerId).WithError(err).Error("unexpected error transmitting link fault") - } - }) - }) - - close(self.closeNotify) - } + }) } diff --git a/router/link/link_events.go b/router/link/link_events.go index 9392d7a44..1f12006a8 100644 --- a/router/link/link_events.go +++ b/router/link/link_events.go @@ -46,7 +46,7 @@ func (self *removeLinkDest) Handle(registry *linkRegistryImpl) { delete(registry.destinations, self.id) if dest != nil { for _, state := range dest.linkMap { - state.status = StatusDestRemoved + state.updateStatus(StatusDestRemoved) if link, _ := registry.GetLink(state.linkId); link != nil { if err := link.Close(); err != nil { pfxlog.Logger(). @@ -171,7 +171,7 @@ func (self *dialRequest) Handle(registry *linkRegistryImpl) { WithField("address", self.dial.Address). WithField("linkKey", linkKey) - if link, found := registry.linkMap[linkKey]; found { + if link, found := registry.GetLink(linkKey); found { registry.SendRouterLinkMessage(link, self.ctrlCh) continue } @@ -214,7 +214,9 @@ func (self *updateLinkStatusForLink) Handle(registry *linkRegistryImpl) { log := pfxlog.Logger().WithField("linkKey", link.Key()).WithField("linkId", link.Id()) dest, found := registry.destinations[link.DestinationId()] if !found { - log.WithField("linkDest", link.DestinationId()).Warnf("unable to mark link as %s, link destination not present in registry", self.status) + if link.IsDialed() { // if link was created by listener, rather than dialer we may not have an entry for it + log.WithField("linkDest", link.DestinationId()).Warnf("unable to mark link as %s, link destination not present in registry", self.status) + } return } @@ -230,33 +232,56 @@ func (self *updateLinkStatusForLink) Handle(registry *linkRegistryImpl) { return } - state.status = self.status + state.updateStatus(self.status) if state.status == StatusEstablished { state.connectedCount++ state.retryDelay = time.Duration(0) + state.ctrlsNotified = false + registry.triggerNotify() } if state.status == StatusLinkFailed { state.retryDelay = time.Duration(0) state.nextDial = time.Now() registry.evaluateLinkState(state) + state.addPendingLinkFault(link.Id(), link.Iteration()) } } -type updateLinkState struct { - linkState *linkState - status linkStatus +type addLinkFaultForReplacedLink struct { + link xlink.Xlink } -func (self *updateLinkState) Handle(registry *linkRegistryImpl) { - state := self.linkState - if state.status == StatusDestRemoved { +func (self *addLinkFaultForReplacedLink) Handle(registry *linkRegistryImpl) { + link := self.link + log := pfxlog.Logger().WithField("linkKey", link.Key()).WithField("linkId", link.Id()) + dest, found := registry.destinations[link.DestinationId()] + if !found { + if link.IsDialed() { // if link was created by listener, rather than dialer we may not have an entry for it + log.WithField("linkDest", link.DestinationId()).Info("link destination not present in registry") + } + return + } + + state, found := dest.linkMap[link.Key()] + if !found { + if link.IsDialed() { // if link was created by listener, rather than dialer we may not have an entry for it + log.WithField("linkDest", link.DestinationId()).Info("link state not present in registry") + } return } - state.status = self.status - if state.status == StatusDialFailed { - state.dialFailed(registry) + state.addPendingLinkFault(link.Id(), link.Iteration()) +} + +type updateLinkStatusToDialFailed struct { + linkState *linkState +} + +func (self *updateLinkStatusToDialFailed) Handle(registry *linkRegistryImpl) { + if self.linkState.status == StatusDialing { + self.linkState.updateStatus(StatusDialFailed) + self.linkState.dialFailed(registry) } } @@ -283,7 +308,7 @@ func (self *inspectLinkStatesEvent) Handle(registry *linkRegistryImpl) { Id: state.linkId, Key: state.linkKey, Status: state.status.String(), - DialAttempts: state.dialAttempts, + DialAttempts: state.dialAttempts.Load(), ConnectedCount: state.connectedCount, RetryDelay: state.retryDelay.String(), NextDial: state.nextDial.Format(time.RFC3339), @@ -292,6 +317,7 @@ func (self *inspectLinkStatesEvent) Handle(registry *linkRegistryImpl) { TargetBinding: state.listener.LocalBinding, DialerGroups: state.dialer.GetGroups(), DialerBinding: state.dialer.GetBinding(), + CtrlsNotified: state.ctrlsNotified, } if inspectLinkState.TargetBinding == "" { inspectLinkState.TargetBinding = "default" @@ -316,3 +342,28 @@ func (self *inspectLinkStatesEvent) GetResults(timeout time.Duration) ([]*inspec return nil, errors.New("timed out waiting for result") } } + +type markNewLinksNotified struct { + links []stateAndLink +} + +func (self *markNewLinksNotified) Handle(*linkRegistryImpl) { + for _, pair := range self.links { + if pair.state.status == StatusEstablished { + pair.state.ctrlsNotified = true + } + } +} + +type markFaultedLinksNotified struct { + successfullySent []stateAndFaults +} + +func (self *markFaultedLinksNotified) Handle(*linkRegistryImpl) { + for _, pair := range self.successfullySent { + state := pair.state + for _, fault := range pair.faults { + state.clearFault(fault) + } + } +} diff --git a/router/link/link_registry.go b/router/link/link_registry.go index fe4d1ecc5..e1a4fafa3 100644 --- a/router/link/link_registry.go +++ b/router/link/link_registry.go @@ -24,6 +24,7 @@ import ( "github.com/openziti/channel/v2/protobufs" "github.com/openziti/foundation/v2/goroutines" "github.com/openziti/identity" + "github.com/openziti/ziti/common/capabilities" "github.com/openziti/ziti/common/inspect" "github.com/openziti/ziti/common/pb/ctrl_pb" "github.com/openziti/ziti/router/env" @@ -40,6 +41,7 @@ type Env interface { GetXlinkDialers() []xlink.Dialer GetCloseNotify() <-chan struct{} GetLinkDialerPool() goroutines.Pool + GetRateLimiterPool() goroutines.Pool } func NewLinkRegistry(routerEnv Env) xlink.Registry { @@ -51,6 +53,7 @@ func NewLinkRegistry(routerEnv Env) xlink.Registry { env: routerEnv, destinations: map[string]*linkDest{}, linkStateQueue: &linkStateHeap{}, + triggerNotifyC: make(chan struct{}, 1), } go result.run() @@ -59,36 +62,39 @@ func NewLinkRegistry(routerEnv Env) xlink.Registry { } type linkRegistryImpl struct { - linkMap map[string]xlink.Xlink - linkByIdMap map[string]xlink.Xlink + linkMapLocks sync.RWMutex + linkMap map[string]xlink.Xlink + linkByIdMap map[string]xlink.Xlink sync.Mutex ctrls env.NetworkControllers - env Env - destinations map[string]*linkDest - linkStateQueue *linkStateHeap - events chan event + env Env + destinations map[string]*linkDest + linkStateQueue *linkStateHeap + events chan event + triggerNotifyC chan struct{} + notifyInProgress atomic.Bool } func (self *linkRegistryImpl) GetLink(linkKey string) (xlink.Xlink, bool) { - self.Lock() - defer self.Unlock() + self.linkMapLocks.RLock() + defer self.linkMapLocks.RUnlock() val, found := self.linkMap[linkKey] return val, found } func (self *linkRegistryImpl) GetLinkById(linkId string) (xlink.Xlink, bool) { - self.Lock() - defer self.Unlock() + self.linkMapLocks.RLock() + defer self.linkMapLocks.RUnlock() link, found := self.linkByIdMap[linkId] return link, found } func (self *linkRegistryImpl) DebugForgetLink(linkId string) bool { - self.Lock() - defer self.Unlock() + self.linkMapLocks.Lock() + defer self.linkMapLocks.Unlock() if link := self.linkByIdMap[linkId]; link != nil { delete(self.linkByIdMap, linkId) delete(self.linkMap, link.Key()) @@ -112,17 +118,19 @@ func (self *linkRegistryImpl) DialSucceeded(link xlink.Xlink) (xlink.Xlink, bool func (self *linkRegistryImpl) applyLink(link xlink.Xlink) (xlink.Xlink, bool) { log := logrus.WithField("dest", link.DestinationId()). WithField("linkProtocol", link.LinkProtocol()). - WithField("newLinkId", link.Id()) + WithField("newLinkId", link.Id()). + WithField("newLinkIteration", link.Iteration()) if link.IsClosed() { log.Info("link being registered, but is already closed, skipping registration") return nil, false } - if existing := self.linkMap[link.Key()]; existing != nil { + if existing, _ := self.GetLink(link.Key()); existing != nil { log = log.WithField("currentLinkId", existing.Id()) - // once we have an established link, we'll store the same id on both sides. Once that happens we can't use - // the link id to decide which duplicate to throw away, so we'll use the router ids instead - if existing.Id() < link.Id() || (existing.Id() == link.Id() && self.env.GetRouterId().Token < link.DestinationId()) { + log = log.WithField("currentLinkIteration", existing.Iteration()) + + // if the id is the same we want to throw away the older one, since the new one is a replacement + if existing.Id() < link.Id() { // give the other side a chance to close the link first and report it as a duplicate time.AfterFunc(30*time.Second, func() { if err := link.Close(); err != nil { @@ -131,47 +139,65 @@ func (self *linkRegistryImpl) applyLink(link xlink.Xlink) (xlink.Xlink, bool) { }) return existing, false } - log.Info("duplicate link detected. closing current link (current link id is > than new link id)") - legacyCtl := self.useLegacyLinkMgmtForOldCtrl() + // make sure we don't block the registry loop + go func() { + log.Info("duplicate link detected. closing current link (current link id is >= than new link id)") - self.ctrls.ForEach(func(ctrlId string, ch channel.Channel) { - // report link fault, then close link after allowing some time for circuits to be re-routed - fault := &ctrl_pb.Fault{ - Id: existing.Id(), - Subject: ctrl_pb.FaultSubject_LinkDuplicate, - } + legacyCtl := self.useLegacyLinkMgmtForOldCtrl() - if legacyCtl { - fault.Subject = ctrl_pb.FaultSubject_LinkFault - } + self.ctrls.ForEach(func(ctrlId string, ch channel.Channel) { + // report link fault, then close link after allowing some time for circuits to be re-routed + fault := &ctrl_pb.Fault{ + Id: existing.Id(), + Subject: ctrl_pb.FaultSubject_LinkDuplicate, + Iteration: existing.Iteration(), + } - if err := protobufs.MarshalTyped(fault).Send(ch); err != nil { - log.WithField("ctrlId", ctrlId). - WithError(err). - Error("failed to send router fault when duplicate link detected") - } - }) + if legacyCtl { + fault.Subject = ctrl_pb.FaultSubject_LinkFault + } - time.AfterFunc(5*time.Minute, func() { - _ = existing.Close() - }) + if err := protobufs.MarshalTyped(fault).WithTimeout(time.Second).SendAndWaitForWire(ch); err != nil { + log.WithField("ctrlId", ctrlId). + WithError(err). + Error("failed to send router fault when duplicate link detected") + } + }) + + time.AfterFunc(5*time.Minute, func() { + _ = existing.Close() + }) + }() } + + self.linkMapLocks.Lock() self.linkMap[link.Key()] = link self.linkByIdMap[link.Id()] = link + self.linkMapLocks.Unlock() + self.updateLinkStateEstablished(link) - self.SendRouterLinkMessage(link, self.ctrls.AllResponsiveCtrlChannels()...) return nil, true } func (self *linkRegistryImpl) LinkClosed(link xlink.Xlink) { - self.Lock() - defer self.Unlock() + markLinkStateClosed := false + self.linkMapLocks.Lock() if val := self.linkMap[link.Key()]; val == link { delete(self.linkMap, link.Key()) - self.updateLinkStateClosed(link) // only update link state to closed if this was the current link + markLinkStateClosed = true // only update link state to closed if this was the current link + } + + if val := self.linkByIdMap[link.Id()]; val == link { + delete(self.linkByIdMap, link.Id()) + } + self.linkMapLocks.Unlock() + + if markLinkStateClosed { + self.updateLinkStateClosed(link) + } else { + self.addLinkFaultForReplacedLink(link) } - delete(self.linkByIdMap, link.Id()) } func (self *linkRegistryImpl) Shutdown() { @@ -193,6 +219,7 @@ func (self *linkRegistryImpl) SendRouterLinkMessage(link xlink.Xlink, channels . DestRouterId: link.DestinationId(), LinkProtocol: link.LinkProtocol(), DialAddress: link.DialAddress(), + Iteration: link.Iteration(), }, }, } @@ -202,9 +229,17 @@ func (self *linkRegistryImpl) SendRouterLinkMessage(link xlink.Xlink, channels . WithField("dest", link.DestinationId()). WithField("linkProtocol", link.LinkProtocol()) + if len(channels) == 0 { + log.Info("no controllers available to notify of link") + } + for _, ch := range channels { - if err := protobufs.MarshalTyped(linkMsg).Send(ch); err != nil { - log.WithError(err).Error("error sending router link message") + if !capabilities.IsCapable(ch, capabilities.ControllerSingleRouterLinkSource) || link.IsDialed() { + if err := protobufs.MarshalTyped(linkMsg).Send(ch); err != nil { + log.WithError(err).Error("error sending router link message") + } + log.WithField("ctrlId", ch.Id()).Info("notified controller of new link") + } } } @@ -230,8 +265,8 @@ func (self *linkRegistryImpl) Run(env.RouterEnv) error { func (self *linkRegistryImpl) Iter() <-chan xlink.Xlink { result := make(chan xlink.Xlink, len(self.linkMap)) go func() { - self.Lock() - defer self.Unlock() + self.linkMapLocks.RLock() + defer self.linkMapLocks.RUnlock() for _, link := range self.linkMap { select { @@ -245,14 +280,22 @@ func (self *linkRegistryImpl) Iter() <-chan xlink.Xlink { } func (self *linkRegistryImpl) NotifyOfReconnect(ch channel.Channel) { + self.Lock() + defer self.Unlock() + + alwaysSend := !capabilities.IsCapable(ch, capabilities.ControllerSingleRouterLinkSource) + routerLinks := &ctrl_pb.RouterLinks{} for link := range self.Iter() { - routerLinks.Links = append(routerLinks.Links, &ctrl_pb.RouterLinks_RouterLink{ - Id: link.Id(), - DestRouterId: link.DestinationId(), - LinkProtocol: link.LinkProtocol(), - DialAddress: link.DialAddress(), - }) + if alwaysSend || link.IsDialed() { + routerLinks.Links = append(routerLinks.Links, &ctrl_pb.RouterLinks_RouterLink{ + Id: link.Id(), + DestRouterId: link.DestinationId(), + LinkProtocol: link.LinkProtocol(), + DialAddress: link.DialAddress(), + Iteration: link.Iteration(), + }) + } } if err := protobufs.MarshalTyped(routerLinks).Send(ch); err != nil { @@ -288,6 +331,24 @@ func (self *linkRegistryImpl) DialRequested(ctrlCh channel.Channel, dial *ctrl_p }) } +func (self *linkRegistryImpl) markNewLinksNotified(links []stateAndLink) { + self.queueEvent(&markNewLinksNotified{ + links: links, + }) +} + +func (self *linkRegistryImpl) markFaultedLinksNotified(successfullySent []stateAndFaults) { + self.queueEvent(&markFaultedLinksNotified{ + successfullySent: successfullySent, + }) +} + +func (self *linkRegistryImpl) dialFailed(state *linkState) { + self.queueEvent(&updateLinkStatusToDialFailed{ + linkState: state, + }) +} + func (self *linkRegistryImpl) queueEvent(evt event) { select { case <-self.env.GetCloseNotify(): @@ -306,8 +367,11 @@ func (self *linkRegistryImpl) run() { select { case evt := <-self.events: evt.Handle(self) + case <-self.triggerNotifyC: + self.notifyControllersOfLinks() case <-queueCheckTicker.C: self.evaluateLinkStateQueue() + self.notifyControllersOfLinks() case <-fullScanTicker.C: self.evaluateDestinations() case <-self.env.GetCloseNotify(): @@ -316,6 +380,13 @@ func (self *linkRegistryImpl) run() { } } +func (self *linkRegistryImpl) triggerNotify() { + select { + case self.triggerNotifyC <- struct{}{}: + default: + } +} + func (self *linkRegistryImpl) evaluateLinkStateQueue() { now := time.Now() for len(*self.linkStateQueue) > 0 { @@ -341,7 +412,7 @@ func (self *linkRegistryImpl) evaluateDestinations() { // If the link is not valid, allow it to be re-dialed state.retryDelay = time.Duration(0) state.nextDial = time.Now() - state.status = StatusLinkFailed + state.updateStatus(StatusLinkFailed) } else { hasEstablishedLinks = true } @@ -365,8 +436,9 @@ func (self *linkRegistryImpl) evaluateLinkState(state *linkState) { couldDial := state.status != StatusEstablished && state.status != StatusDialing && state.nextDial.Before(time.Now()) if couldDial { - state.status = StatusDialing - state.dialAttempts++ + state.updateStatus(StatusDialing) + iteration := state.dialAttempts.Add(1) + log = log.WithField("linkId", state.linkId).WithField("iteration", iteration) log.Info("queuing link to dial") err := self.env.GetLinkDialerPool().QueueOrError(func() { @@ -381,10 +453,7 @@ func (self *linkRegistryImpl) evaluateLinkState(state *linkState) { link, err := state.dialer.Dial(state) if err != nil { log.WithError(err).Error("error dialing link") - self.queueEvent(&updateLinkState{ - linkState: state, - status: StatusDialFailed, - }) + self.dialFailed(state) return } @@ -393,16 +462,13 @@ func (self *linkRegistryImpl) evaluateLinkState(state *linkState) { if existing != nil { self.updateLinkStateEstablished(link) } else { - self.queueEvent(&updateLinkState{ - linkState: state, - status: StatusDialFailed, - }) + self.dialFailed(state) } } }) if err != nil { log.WithError(err).Error("unable to queue link dial, see pool error") - state.status = StatusQueueFailed + state.updateStatus(StatusQueueFailed) state.dialFailed(self) } } @@ -422,6 +488,12 @@ func (self *linkRegistryImpl) updateLinkStateClosed(link xlink.Xlink) { }) } +func (self *linkRegistryImpl) addLinkFaultForReplacedLink(link xlink.Xlink) { + self.queueEvent(&addLinkFaultForReplacedLink{ + link: link, + }) +} + func (self *linkRegistryImpl) Inspect(timeout time.Duration) *inspect.LinksInspectResult { evt := &inspectLinkStatesEvent{ result: atomic.Pointer[[]*inspect.LinkDest]{}, @@ -465,3 +537,180 @@ func (self *linkRegistryImpl) GetLinkKey(dialerBinding, protocol, dest, listener return fmt.Sprintf("%s->%s:%s->%s", dialerBinding, protocol, dest, listenerBinding) } + +func (self *linkRegistryImpl) notifyControllersOfLinks() { + if self.notifyInProgress.Load() { + pfxlog.Logger().WithField("op", "link-notify").Info("new link notification already in progress, exiting") + return + } + + var links []stateAndLink + var faults []stateAndFaults + + for _, dest := range self.destinations { + for _, state := range dest.linkMap { + if !state.ctrlsNotified { + if state.status == StatusEstablished { + link, _ := self.GetLink(state.linkKey) + if link == nil { + pfxlog.Logger(). + WithField("op", "link-notify"). + WithField("linkId", state.linkId). + Info("link not found for link key on established link, marking failed") + state.updateStatus(StatusDialFailed) + state.dialFailed(self) + } else if link.IsDialed() { + links = append(links, stateAndLink{ + state: state, + link: link, + }) + } + + // if we have an established link, don't send faults for it + if link != nil { + state.clearFaultsForLinkId(link.Id()) + } + } + } + + if len(state.linkFaults) > 0 { + var linkFaults []linkFault + linkFaults = append(linkFaults, state.linkFaults...) + faults = append(faults, stateAndFaults{ + state: state, + faults: linkFaults, + }) + } + } + } + + if len(links) == 0 && len(faults) == 0 { + return + } + + pfxlog.Logger().WithField("op", "link-notify").Info("attempting to queue link notifications") + self.notifyInProgress.Store(true) + err := self.env.GetRateLimiterPool().QueueOrError(func() { + pfxlog.Logger().WithField("op", "link-notify").Info("link notifications starting") + + defer func() { + self.notifyInProgress.Store(false) + pfxlog.Logger().WithField("op", "link-notify").Info("link notifications exiting") + }() + + if len(links) > 0 { + self.sendNewLinks(links) + } + + if len(faults) > 0 { + self.sendLinkFaults(faults) + } + }) + + if err != nil { + pfxlog.Logger().WithField("op", "link-notify").Info("unable to queue link notifications") + self.notifyInProgress.Store(false) + } +} + +func (self *linkRegistryImpl) sendNewLinks(links []stateAndLink) { + routerLinks := &ctrl_pb.RouterLinks{} + for _, pair := range links { + link := pair.link + routerLinks.Links = append(routerLinks.Links, &ctrl_pb.RouterLinks_RouterLink{ + Id: link.Id(), + DestRouterId: link.DestinationId(), + LinkProtocol: link.LinkProtocol(), + DialAddress: link.DialAddress(), + Iteration: link.Iteration(), + }) + } + + allSent := true + for ctrlId, ctrl := range self.ctrls.GetAll() { + connectedChecker := ctrl.Channel().Underlay().(interface{ IsConnected() bool }) + log := pfxlog.Logger().WithField("ctrlId", ctrlId).WithField("op", "link-notify") + if connectedChecker.IsConnected() { + msgEnv := protobufs.MarshalTyped(routerLinks).WithTimeout(10 * time.Second) + if err := msgEnv.SendAndWaitForWire(ctrl.Channel()); err != nil { + log.WithError(err).Error("timeout sending new router links") + allSent = false + + for _, pair := range links { + log.WithField("linkId", pair.link.Id()). + WithField("iteration", pair.link.Iteration()). + Info("failed to notify controller of new link") + } + } else { + for _, pair := range links { + log.WithField("linkId", pair.link.Id()). + WithField("iteration", pair.link.Iteration()). + Info("notified controller of new link") + } + } + } + } + + if allSent { + self.markNewLinksNotified(links) + } +} + +func (self *linkRegistryImpl) sendLinkFaults(list []stateAndFaults) { + var successfullySent []stateAndFaults + for _, item := range list { + var sent []linkFault + + for _, fault := range item.faults { + allSent := true + for ctrlId, ctrl := range self.ctrls.GetAll() { + faultMsg := &ctrl_pb.Fault{ + Subject: ctrl_pb.FaultSubject_LinkFault, + Id: fault.linkId, + Iteration: fault.iteration, + } + + log := pfxlog.Logger().WithField("ctrlId", ctrlId). + WithField("op", "link-notify"). + WithField("linkId", fault.linkId). + WithField("iteration", fault.iteration) + + connectedChecker := ctrl.Channel().Underlay().(interface{ IsConnected() bool }) + + if connectedChecker.IsConnected() { + msgEnv := protobufs.MarshalTyped(faultMsg).WithTimeout(10 * time.Second) + if err := msgEnv.SendAndWaitForWire(ctrl.Channel()); err != nil { + log.WithError(err).Error("timeout sending link fault") + allSent = false + log.Info("failed to notify controller of link fault") + } else { + log.Info("notified controller of link fault") + } + } + } + if allSent { + sent = append(sent, fault) + } + } + if len(sent) > 0 { + successfullySent = append(successfullySent, stateAndFaults{ + state: item.state, + faults: sent, + }) + } + } + + if len(successfullySent) > 0 { + self.markFaultedLinksNotified(successfullySent) + } +} + +type stateAndLink struct { + state *linkState + link xlink.Xlink +} + +type stateAndFaults struct { + state *linkState + faults []linkFault +} diff --git a/router/link/link_state.go b/router/link/link_state.go index b42fd76f4..c90452f20 100644 --- a/router/link/link_state.go +++ b/router/link/link_state.go @@ -18,8 +18,10 @@ package link import ( "container/heap" + "github.com/michaelquigley/pfxlog" "github.com/openziti/ziti/common/pb/ctrl_pb" "github.com/openziti/ziti/router/xlink" + "sync/atomic" "time" ) @@ -59,18 +61,36 @@ func (self *linkDest) update(update *linkDestUpdate) { } } +type linkFault struct { + linkId string + iteration uint32 +} + type linkState struct { linkKey string linkId string status linkStatus - dialAttempts uint - connectedCount uint + dialAttempts atomic.Uint64 + connectedCount uint64 retryDelay time.Duration nextDial time.Time dest *linkDest listener *ctrl_pb.Listener dialer xlink.Dialer - allowedDials int + allowedDials int64 + ctrlsNotified bool + linkFaults []linkFault +} + +func (self *linkState) updateStatus(status linkStatus) { + log := pfxlog.Logger(). + WithField("key", self.linkKey). + WithField("oldState", self.status). + WithField("newState", status). + WithField("linkId", self.linkId). + WithField("iteration", self.dialAttempts.Load()) + self.status = status + log.Info("status updated") } func (self *linkState) GetLinkKey() string { @@ -97,6 +117,47 @@ func (self *linkState) GetRouterVersion() string { return self.dest.version } +func (self *linkState) GetIteration() uint32 { + return uint32(self.dialAttempts.Load()) +} + +func (self *linkState) addPendingLinkFault(linkId string, iteration uint32) { + for _, fault := range self.linkFaults { + if fault.linkId == linkId { + if fault.iteration < iteration { + fault.iteration = iteration + } + return + } + } + self.linkFaults = append(self.linkFaults, linkFault{ + linkId: linkId, + iteration: iteration, + }) +} + +func (self *linkState) clearFaultsForLinkId(linkId string) { + faults := self.linkFaults + self.linkFaults = nil + + for _, fault := range faults { + if fault.linkId != linkId { + self.linkFaults = append(self.linkFaults, fault) + } + } +} + +func (self *linkState) clearFault(toClear linkFault) { + faults := self.linkFaults + self.linkFaults = nil + + for _, fault := range faults { + if fault.linkId != toClear.linkId || fault.iteration > toClear.iteration { + self.linkFaults = append(self.linkFaults, fault) + } + } +} + func (self *linkState) dialFailed(registry *linkRegistryImpl) { if self.allowedDials > 0 { self.allowedDials-- diff --git a/router/router.go b/router/router.go index 7cbd8cfe2..59cfb2a3c 100644 --- a/router/router.go +++ b/router/router.go @@ -349,10 +349,10 @@ func (self *Router) startProfiling() { } func (self *Router) initRateLimiterPool() error { - linkDialerPoolConfig := goroutines.PoolConfig{ + rateLimiterPoolConfig := goroutines.PoolConfig{ QueueSize: uint32(self.forwarder.Options.RateLimiter.QueueLength), MinWorkers: 0, - MaxWorkers: uint32(self.forwarder.Options.LinkDial.WorkerCount), + MaxWorkers: uint32(self.forwarder.Options.RateLimiter.WorkerCount), IdleTime: 30 * time.Second, CloseNotify: self.GetCloseNotify(), PanicHandler: func(err interface{}) { @@ -360,9 +360,9 @@ func (self *Router) initRateLimiterPool() error { }, } - fabricMetrics.ConfigureGoroutinesPoolMetrics(&linkDialerPoolConfig, self.GetMetricsRegistry(), "pool.link.dialer") + fabricMetrics.ConfigureGoroutinesPoolMetrics(&rateLimiterPoolConfig, self.GetMetricsRegistry(), "pool.rate_limiter") - rateLimiterPool, err := goroutines.NewPool(linkDialerPoolConfig) + rateLimiterPool, err := goroutines.NewPool(rateLimiterPoolConfig) if err != nil { return errors.Wrap(err, "error creating rate limited pool") } @@ -579,7 +579,7 @@ func (self *Router) connectToController(addr transport.Address, bindHandler chan if buf, err := proto.Marshal(listeners); err != nil { return errors.Wrap(err, "unable to marshal Listeners") } else { - attributes[int32(ctrl_pb.ContentType_ListenersHeader)] = buf + attributes[int32(ctrl_pb.ControlHeaders_ListenersHeader)] = buf } } @@ -592,7 +592,7 @@ func (self *Router) connectToController(addr transport.Address, bindHandler chan if buf, err := proto.Marshal(routerMeta); err != nil { return errors.Wrap(err, "unable to router metadata") } else { - attributes[int32(ctrl_pb.ContentType_RouterMetadataHeader)] = buf + attributes[int32(ctrl_pb.ControlHeaders_RouterMetadataHeader)] = buf } var channelRef concurrenz.AtomicValue[channel.Channel] @@ -620,6 +620,11 @@ func (self *Router) connectToController(addr transport.Address, bindHandler chan } channelRef.Store(ch) + // If there are multiple controllers we may have to catch up the controllers that connected later + // with things that have already happened because we had state from other controllers, such as + // links + reconnectHandler() + return nil } diff --git a/router/xgress_edge/listener.go b/router/xgress_edge/listener.go index 76739563b..ae3e8c515 100644 --- a/router/xgress_edge/listener.go +++ b/router/xgress_edge/listener.go @@ -19,13 +19,11 @@ package xgress_edge import ( "encoding/binary" "fmt" - "math/big" "time" "github.com/openziti/ziti/common/capabilities" "github.com/openziti/ziti/common/cert" fabricMetrics "github.com/openziti/ziti/common/metrics" - "github.com/openziti/ziti/common/pb/ctrl_pb" "github.com/openziti/ziti/common/pb/edge_ctrl_pb" "github.com/openziti/ziti/controller/idgen" "github.com/pkg/errors" @@ -207,14 +205,7 @@ func (self *edgeClientConn) processBind(req *channel.Message, ch channel.Channel return } - supportsCreateTerminatorV2 := false - headers := ctrlCh.Underlay().Headers() - if val, found := headers[int32(ctrl_pb.ContentType_CapabilitiesHeader)]; found { - capabilitiesMask := &big.Int{} - capabilitiesMask.SetBytes(val) - supportsCreateTerminatorV2 = capabilitiesMask.Bit(capabilities.ControllerCreateTerminatorV2) == 1 - } - + supportsCreateTerminatorV2 := capabilities.IsCapable(ctrlCh, capabilities.ControllerCreateTerminatorV2) if supportsCreateTerminatorV2 { self.processBindV2(req, ch) } else { diff --git a/router/xlink/xlink.go b/router/xlink/xlink.go index 87e423f4b..9bbbb237d 100644 --- a/router/xlink/xlink.go +++ b/router/xlink/xlink.go @@ -18,12 +18,12 @@ package xlink import ( "github.com/openziti/channel/v2" - "github.com/openziti/ziti/common/inspect" - "github.com/openziti/ziti/common/pb/ctrl_pb" - "github.com/openziti/ziti/router/xgress" "github.com/openziti/identity" "github.com/openziti/metrics" "github.com/openziti/transport/v2" + "github.com/openziti/ziti/common/inspect" + "github.com/openziti/ziti/common/pb/ctrl_pb" + "github.com/openziti/ziti/router/xgress" "time" ) @@ -94,6 +94,7 @@ type Dial interface { GetAddress() string GetLinkProtocol() string GetRouterVersion() string + GetIteration() uint32 } type BackoffConfig interface { @@ -129,11 +130,13 @@ type Xlink interface { DestVersion() string LinkProtocol() string DialAddress() string - HandleCloseNotification(f func()) + CloseOnce(f func()) IsClosed() bool InspectLink() *inspect.LinkInspectDetail GetAddresses() []*ctrl_pb.LinkConn IsDialed() bool + Iteration() uint32 + AreFaultsSent() bool } type Forwarder interface { diff --git a/router/xlink_transport/dialer.go b/router/xlink_transport/dialer.go index 4f5d2ed33..21cb4e6de 100644 --- a/router/xlink_transport/dialer.go +++ b/router/xlink_transport/dialer.go @@ -77,14 +77,14 @@ func (self *dialer) Dial(dial xlink.Dial) (xlink.Xlink, error) { xli, err = self.dialSingle(linkId, address, connId, dial) } if err != nil { - return nil, errors.Wrapf(err, "error dialing outgoing link [l/%s]", linkId.Token) + return nil, errors.Wrapf(err, "error dialing outgoing link [l/%s@%v]", linkId.Token, dial.GetIteration()) } if err = self.acceptor.Accept(xli); err != nil { if closeErr := xli.Close(); closeErr != nil { pfxlog.Logger().WithError(closeErr).WithField("acceptErr", err).Error("error closing link after accept error") } - return nil, errors.Wrapf(err, "error accepting link [l/%s]", linkId.Token) + return nil, errors.Wrapf(err, "error accepting link [l/%s@%v]", linkId.Token, dial.GetIteration()) } return xli, nil @@ -94,13 +94,16 @@ func (self *dialer) Dial(dial xlink.Dial) (xlink.Xlink, error) { func (self *dialer) dialSplit(linkId *identity.TokenId, address transport.Address, connId string, dial xlink.Dial) (xlink.Xlink, error) { logrus.Debugf("dialing link with split payload/ack channels [l/%s]", linkId.Token) - payloadDialer := channel.NewClassicDialerWithBindAddress(linkId, address, self.config.localBinding, map[int32][]byte{ + headers := channel.Headers{ LinkHeaderRouterId: []byte(self.id.Token), LinkHeaderConnId: []byte(connId), LinkHeaderType: {byte(PayloadChannel)}, LinkHeaderRouterVersion: []byte(dial.GetRouterVersion()), LinkHeaderBinding: []byte(self.GetBinding()), - }) + } + headers.PutUint32Header(LinkHeaderIteration, dial.GetIteration()) + + payloadDialer := channel.NewClassicDialerWithBindAddress(linkId, address, self.config.localBinding, headers) logrus.Debugf("dialing payload channel for [l/%s]", linkId.Token) @@ -113,6 +116,7 @@ func (self *dialer) dialSplit(linkId *identity.TokenId, address transport.Addres routerVersion: dial.GetRouterVersion(), linkProtocol: dial.GetLinkProtocol(), dialAddress: dial.GetAddress(), + iteration: dial.GetIteration(), dialed: true, }, } @@ -124,13 +128,16 @@ func (self *dialer) dialSplit(linkId *identity.TokenId, address transport.Addres logrus.Debugf("dialing ack channel for [l/%s]", linkId.Token) - ackDialer := channel.NewClassicDialerWithBindAddress(linkId, address, self.config.localBinding, map[int32][]byte{ + headers = channel.Headers{ LinkHeaderRouterId: []byte(self.id.Token), LinkHeaderConnId: []byte(connId), LinkHeaderType: {byte(AckChannel)}, LinkHeaderRouterVersion: []byte(dial.GetRouterVersion()), LinkHeaderBinding: []byte(self.GetBinding()), - }) + } + headers.PutUint32Header(LinkHeaderIteration, dial.GetIteration()) + + ackDialer := channel.NewClassicDialerWithBindAddress(linkId, address, self.config.localBinding, headers) _, err = channel.NewChannelWithTransportConfiguration("l/"+linkId.Token, ackDialer, channel.BindHandlerF(bindHandler.bindAckChannel), self.config.options, self.transportConfig) if err != nil { @@ -144,12 +151,15 @@ func (self *dialer) dialSplit(linkId *identity.TokenId, address transport.Addres func (self *dialer) dialSingle(linkId *identity.TokenId, address transport.Address, connId string, dial xlink.Dial) (xlink.Xlink, error) { logrus.Debugf("dialing link with single channel [l/%s]", linkId.Token) - payloadDialer := channel.NewClassicDialerWithBindAddress(linkId, address, self.config.localBinding, map[int32][]byte{ + headers := channel.Headers{ LinkHeaderRouterId: []byte(self.id.Token), LinkHeaderConnId: []byte(connId), LinkHeaderRouterVersion: []byte(dial.GetRouterVersion()), LinkHeaderBinding: []byte(self.GetBinding()), - }) + } + headers.PutUint32Header(LinkHeaderIteration, dial.GetIteration()) + + payloadDialer := channel.NewClassicDialerWithBindAddress(linkId, address, self.config.localBinding, headers) bindHandler := &dialBindHandler{ dialer: self, @@ -160,6 +170,7 @@ func (self *dialer) dialSingle(linkId *identity.TokenId, address transport.Addre linkProtocol: dial.GetLinkProtocol(), routerVersion: dial.GetRouterVersion(), dialAddress: dial.GetAddress(), + iteration: dial.GetIteration(), dialed: true, }, } diff --git a/router/xlink_transport/factory.go b/router/xlink_transport/factory.go index 2aa2bff47..4a8c56618 100644 --- a/router/xlink_transport/factory.go +++ b/router/xlink_transport/factory.go @@ -19,10 +19,10 @@ package xlink_transport import ( "fmt" "github.com/openziti/channel/v2" - "github.com/openziti/ziti/router/xlink" "github.com/openziti/identity" "github.com/openziti/metrics" "github.com/openziti/transport/v2" + "github.com/openziti/ziti/router/xlink" ) type channelType byte @@ -33,6 +33,7 @@ const ( LinkHeaderRouterId = 2 LinkHeaderRouterVersion = 3 LinkHeaderBinding = 4 + LinkHeaderIteration = 5 PayloadChannel channelType = 1 AckChannel channelType = 2 diff --git a/router/xlink_transport/listener.go b/router/xlink_transport/listener.go index 94b38edac..2815dbf32 100644 --- a/router/xlink_transport/listener.go +++ b/router/xlink_transport/listener.go @@ -97,12 +97,13 @@ func (self *listener) BindChannel(binding channel.Binding) error { WithField("linkProtocol", self.GetLinkProtocol()). WithField("linkId", binding.GetChannel().Id()) - headers := binding.GetChannel().Underlay().Headers() + headers := channel.Headers(binding.GetChannel().Underlay().Headers()) var chanType channelType routerId := "" routerVersion := "" dialerBinding := "" + var iteration uint32 if headers != nil { if v, ok := headers[LinkHeaderRouterId]; ok { @@ -121,12 +122,17 @@ func (self *listener) BindChannel(binding channel.Binding) error { dialerBinding = string(val) log = log.WithField("dialerBinding", dialerBinding) } + if val, ok := headers.GetUint32Header(LinkHeaderIteration); ok { + iteration = val + log = log.WithField("iteration", iteration) + } } linkMeta := &linkMetadata{ routerId: routerId, routerVersion: routerVersion, dialerBinding: dialerBinding, + iteration: iteration, } if chanType != 0 { @@ -196,6 +202,7 @@ func (self *listener) getOrCreateSplitLink(id string, linkMeta *linkMetadata, bi routerVersion: linkMeta.routerVersion, linkProtocol: self.GetLinkProtocol(), dialAddress: self.GetAdvertisement(), + iteration: linkMeta.iteration, dialed: false, }, eventTime: time.Now(), @@ -232,6 +239,7 @@ func (self *listener) bindNonSplitChannel(binding channel.Binding, linkMeta *lin routerVersion: linkMeta.routerVersion, linkProtocol: self.GetLinkProtocol(), dialAddress: self.GetAdvertisement(), + iteration: linkMeta.iteration, dialed: false, } @@ -288,4 +296,5 @@ type linkMetadata struct { routerId string routerVersion string dialerBinding string + iteration uint32 } diff --git a/router/xlink_transport/xlink.go b/router/xlink_transport/xlink.go index 2737cc56c..928c02782 100644 --- a/router/xlink_transport/xlink.go +++ b/router/xlink_transport/xlink.go @@ -18,10 +18,10 @@ package xlink_transport import ( "github.com/openziti/channel/v2" + "github.com/openziti/metrics" "github.com/openziti/ziti/common/inspect" "github.com/openziti/ziti/common/pb/ctrl_pb" "github.com/openziti/ziti/router/xgress" - "github.com/openziti/metrics" "sync/atomic" ) @@ -33,9 +33,11 @@ type impl struct { routerVersion string linkProtocol string dialAddress string - closeNotified atomic.Bool + closed atomic.Bool + faultsSent atomic.Bool droppedMsgMeter metrics.Meter dialed bool + iteration uint32 } func (self *impl) Id() string { @@ -46,6 +48,10 @@ func (self *impl) Key() string { return self.key } +func (self *impl) Iteration() uint32 { + return self.iteration +} + func (self *impl) Init(metricsRegistry metrics.Registry) error { if self.droppedMsgMeter == nil { self.droppedMsgMeter = metricsRegistry.Meter("link.dropped_msgs:" + self.id) @@ -83,10 +89,14 @@ func (self *impl) Close() error { } func (self *impl) CloseNotified() error { - self.closeNotified.Store(true) + self.faultsSent.Store(true) return self.Close() } +func (self *impl) AreFaultsSent() bool { + return self.faultsSent.Load() +} + func (self *impl) DestinationId() string { return self.routerId } @@ -107,8 +117,8 @@ func (self *impl) IsDialed() bool { return self.dialed } -func (self *impl) HandleCloseNotification(f func()) { - if self.closeNotified.CompareAndSwap(false, true) { +func (self *impl) CloseOnce(f func()) { + if self.closed.CompareAndSwap(false, true) { f() } } @@ -124,6 +134,7 @@ func (self *impl) InspectCircuit(detail *inspect.CircuitInspectDetail) { func (self *impl) InspectLink() *inspect.LinkInspectDetail { return &inspect.LinkInspectDetail{ Id: self.Id(), + Iteration: self.Iteration(), Key: self.key, Split: false, Protocol: self.LinkProtocol(), diff --git a/router/xlink_transport/xlink_split.go b/router/xlink_transport/xlink_split.go index bb7bed055..ca118d156 100644 --- a/router/xlink_transport/xlink_split.go +++ b/router/xlink_transport/xlink_split.go @@ -18,10 +18,10 @@ package xlink_transport import ( "github.com/openziti/channel/v2" + "github.com/openziti/metrics" "github.com/openziti/ziti/common/inspect" "github.com/openziti/ziti/common/pb/ctrl_pb" "github.com/openziti/ziti/router/xgress" - "github.com/openziti/metrics" "github.com/pkg/errors" "sync/atomic" ) @@ -35,9 +35,11 @@ type splitImpl struct { routerVersion string linkProtocol string dialAddress string - closeNotified atomic.Bool + closed atomic.Bool + faultsSent atomic.Bool droppedMsgMeter metrics.Meter dialed bool + iteration uint32 } func (self *splitImpl) Id() string { @@ -48,6 +50,10 @@ func (self *splitImpl) Key() string { return self.key } +func (self *splitImpl) Iteration() uint32 { + return self.iteration +} + func (self *splitImpl) Init(metricsRegistry metrics.Registry) error { if self.droppedMsgMeter == nil { self.droppedMsgMeter = metricsRegistry.Meter("link.dropped_msgs:" + self.id) @@ -80,10 +86,14 @@ func (self *splitImpl) SendControl(msg *xgress.Control) error { } func (self *splitImpl) CloseNotified() error { - self.closeNotified.Store(true) + self.faultsSent.Store(true) return self.Close() } +func (self *splitImpl) AreFaultsSent() bool { + return self.faultsSent.Load() +} + func (self *splitImpl) Close() error { if self.droppedMsgMeter != nil { self.droppedMsgMeter.Dispose() @@ -121,8 +131,8 @@ func (self *splitImpl) DialAddress() string { return self.dialAddress } -func (self *splitImpl) HandleCloseNotification(f func()) { - if self.closeNotified.CompareAndSwap(false, true) { +func (self *splitImpl) CloseOnce(f func()) { + if self.closed.CompareAndSwap(false, true) { f() } } @@ -142,6 +152,7 @@ func (self *splitImpl) InspectCircuit(detail *inspect.CircuitInspectDetail) { func (self *splitImpl) InspectLink() *inspect.LinkInspectDetail { return &inspect.LinkInspectDetail{ Id: self.Id(), + Iteration: self.Iteration(), Key: self.key, Split: true, Protocol: self.LinkProtocol(), diff --git a/tests/control.go b/tests/control.go index dbe408a08..9ba51b3e4 100644 --- a/tests/control.go +++ b/tests/control.go @@ -4,7 +4,10 @@ import ( "github.com/openziti/channel/v2" "github.com/openziti/foundation/v2/versions" "github.com/openziti/transport/v2" + "github.com/openziti/ziti/common/capabilities" + "github.com/openziti/ziti/common/pb/ctrl_pb" "github.com/openziti/ziti/controller" + "math/big" ) func (ctx *FabricTestContext) NewControlChannelListener() channel.UnderlayListener { @@ -14,8 +17,13 @@ func (ctx *FabricTestContext) NewControlChannelListener() channel.UnderlayListen versionHeader, err := versions.StdVersionEncDec.Encode(versions.NewDefaultVersionProvider().AsVersionInfo()) ctx.Req.NoError(err) + + capabilityMask := &big.Int{} + capabilityMask.SetBit(capabilityMask, capabilities.ControllerCreateTerminatorV2, 1) + capabilityMask.SetBit(capabilityMask, capabilities.ControllerSingleRouterLinkSource, 1) headers := map[int32][]byte{ - channel.HelloVersionHeader: versionHeader, + channel.HelloVersionHeader: versionHeader, + int32(ctrl_pb.ControlHeaders_CapabilitiesHeader): capabilityMask.Bytes(), } ctrlChannelListenerConfig := channel.ListenerConfig{ diff --git a/tests/link_test.go b/tests/link_test.go index 7565e76a4..fecbc96a4 100644 --- a/tests/link_test.go +++ b/tests/link_test.go @@ -75,6 +75,10 @@ func (self *testRegistryEnv) GetLinkDialerPool() goroutines.Pool { panic("implement me") } +func (self *testRegistryEnv) GetRateLimiterPool() goroutines.Pool { + panic("implement me") +} + type testDial struct { Key string LinkId string @@ -108,6 +112,10 @@ func (self *testDial) GetRouterVersion() string { return self.RouterVersion } +func (self *testDial) GetIteration() uint32 { + return 1 +} + func setupEnv() link.Env { ctrls := env.NewNetworkControllers(time.Second, nil, env.NewDefaultHeartbeatOptions()) @@ -215,18 +223,19 @@ func Test_DuplicateLinkWithLinkCloseDialer(t *testing.T) { ctrlListener := ctx.NewControlChannelListener() router1 := ctx.startRouter(1) - router1cc, linkCheck1 := testutil.StartLinkTest("router-1", ctrlListener, ctx.Req) + linkChecker := testutil.NewLinkChecker(ctx.Req) + router1cc := testutil.StartLinkTest(linkChecker, "router-1", ctrlListener, ctx.Req) router1Listeners := &ctrl_pb.Listeners{} - if val, found := router1cc.Underlay().Headers()[int32(ctrl_pb.ContentType_ListenersHeader)]; found { + if val, found := router1cc.Underlay().Headers()[int32(ctrl_pb.ControlHeaders_ListenersHeader)]; found { ctx.Req.NoError(proto.Unmarshal(val, router1Listeners)) } router2 := ctx.startRouter(2) - router2cc, linkCheck2 := testutil.StartLinkTest("router-2", ctrlListener, ctx.Req) + router2cc := testutil.StartLinkTest(linkChecker, "router-2", ctrlListener, ctx.Req) router2Listeners := &ctrl_pb.Listeners{} - if val, found := router1cc.Underlay().Headers()[int32(ctrl_pb.ContentType_ListenersHeader)]; found { + if val, found := router1cc.Underlay().Headers()[int32(ctrl_pb.ControlHeaders_ListenersHeader)]; found { ctx.Req.NoError(proto.Unmarshal(val, router1Listeners)) } @@ -258,32 +267,31 @@ func Test_DuplicateLinkWithLinkCloseDialer(t *testing.T) { time.Sleep(time.Second) - linkCheck1.RequireNoErrors() - link1 := linkCheck1.RequireOneActiveLink() + linkChecker.RequireNoErrors() + link1 := linkChecker.RequireOneActiveLink() - linkCheck2.RequireNoErrors() - link2 := linkCheck1.RequireOneActiveLink() + linkChecker.RequireNoErrors() + link2 := linkChecker.RequireOneActiveLink() ctx.Req.Equal(link1.Id, link2.Id) // Test closing control ch to router 1. On reconnect the existing link should get reported ctx.Req.NoError(router1cc.Close()) - _, linkCheck1 = testutil.StartLinkTest("router-1", ctrlListener, ctx.Req) + _ = testutil.StartLinkTest(linkChecker, "router-1", ctrlListener, ctx.Req) time.Sleep(time.Second) - - linkCheck1.RequireNoErrors() - link1 = linkCheck1.RequireOneActiveLink() + linkChecker.RequireNoErrors() + link1 = linkChecker.RequireOneActiveLink() ctx.Req.Equal(link1.Id, link2.Id) // Test closing control ch to router 2. On reconnect the existing link should get reported ctx.Req.NoError(router2cc.Close()) - _, linkCheck2 = testutil.StartLinkTest("router-2", ctrlListener, ctx.Req) + _ = testutil.StartLinkTest(linkChecker, "router-2", ctrlListener, ctx.Req) time.Sleep(time.Second) - linkCheck2.RequireNoErrors() - link2 = linkCheck2.RequireOneActiveLink() + linkChecker.RequireNoErrors() + link2 = linkChecker.RequireOneActiveLink() ctx.Req.Equal(link1.Id, link2.Id) // restart router 1 @@ -294,10 +302,10 @@ func Test_DuplicateLinkWithLinkCloseDialer(t *testing.T) { ctx.Req.NoError(router1.Shutdown()) }() - router1cc, linkCheck1 = testutil.StartLinkTest("router-1", ctrlListener, ctx.Req) + router1cc = testutil.StartLinkTest(linkChecker, "router-1", ctrlListener, ctx.Req) ctx.Req.NoError(protobufs.MarshalTyped(peerUpdates2).WithTimeout(time.Second).SendAndWaitForWire(router1cc)) - linkCheck1.RequireNoErrors() + linkChecker.RequireNoErrors() //time.Sleep(time.Minute) // diff --git a/tests/testutil/linkschecker.go b/tests/testutil/linkschecker.go index 503fdf7f1..574fed6ad 100644 --- a/tests/testutil/linkschecker.go +++ b/tests/testutil/linkschecker.go @@ -1,6 +1,7 @@ package testutil import ( + "fmt" "sync" "time" @@ -15,9 +16,11 @@ import ( ) type TestLink struct { - Id string - Dest string - Failed bool + Id string + Src string + Dest string + FaultCount int + Valid bool } type LinkStateChecker struct { @@ -34,7 +37,7 @@ func (self *LinkStateChecker) reportError(err error) { } } -func (self *LinkStateChecker) HandleLink(msg *channel.Message, _ channel.Channel) { +func (self *LinkStateChecker) HandleLink(msg *channel.Message, ch channel.Channel) { self.Lock() defer self.Unlock() @@ -44,8 +47,22 @@ func (self *LinkStateChecker) HandleLink(msg *channel.Message, _ channel.Channel } for _, link := range routerLinks.Links { - self.links[link.Id] = &TestLink{ - Id: link.Id, + testLink, ok := self.links[link.Id] + if !ok { + self.links[link.Id] = &TestLink{ + Id: link.Id, + Src: ch.Id(), + Dest: link.DestRouterId, + Valid: true, + } + } else { + if testLink.Src != ch.Id() { + self.reportError(fmt.Errorf("source router change for link %v => %v", testLink.Src, ch.Id())) + } + if testLink.Dest != link.DestRouterId { + self.reportError(fmt.Errorf("dest router change for link %v => %v", testLink.Dest, link.DestRouterId)) + } + testLink.Valid = true } } } @@ -64,7 +81,8 @@ func (self *LinkStateChecker) HandleFault(msg *channel.Message, _ channel.Channe if fault.Subject == ctrl_pb.FaultSubject_LinkFault || fault.Subject == ctrl_pb.FaultSubject_LinkDuplicate { if link, found := self.links[fault.Id]; found { - link.Failed = true + link.FaultCount++ + link.Valid = false } else { self.reportError(errors.Errorf("no link with Id %s found", fault.Id)) } @@ -108,7 +126,7 @@ func (self *LinkStateChecker) RequireOneActiveLink() *TestLink { var activeLink *TestLink for _, link := range self.links { - if !link.Failed { + if link.Valid { self.req.Nil(activeLink, "more than one active link found") activeLink = link } @@ -117,13 +135,16 @@ func (self *LinkStateChecker) RequireOneActiveLink() *TestLink { return activeLink } -func StartLinkTest(id string, uf channel.UnderlayFactory, assertions *require.Assertions) (channel.Channel, *LinkStateChecker) { +func NewLinkChecker(assertions *require.Assertions) *LinkStateChecker { checker := &LinkStateChecker{ errorC: make(chan error, 4), links: map[string]*TestLink{}, req: assertions, } + return checker +} +func StartLinkTest(checker *LinkStateChecker, id string, uf channel.UnderlayFactory, assertions *require.Assertions) channel.Channel { bindHandler := func(binding channel.Binding) error { binding.AddReceiveHandlerF(channel.AnyContentType, checker.HandleOther) binding.AddReceiveHandlerF(int32(ctrl_pb.ContentType_VerifyRouterType), func(msg *channel.Message, ch channel.Channel) { @@ -137,5 +158,5 @@ func StartLinkTest(id string, uf channel.UnderlayFactory, assertions *require.As timeoutUF := NewTimeoutUnderlayFactory(uf, 2*time.Second) ch, err := channel.NewChannel(id, timeoutUF, channel.BindHandlerF(bindHandler), channel.DefaultOptions()) assertions.NoError(err) - return ch, checker + return ch } diff --git a/ziti/cmd/demo/root.go b/ziti/cmd/demo/root.go index a0868d05c..f53bcc38f 100644 --- a/ziti/cmd/demo/root.go +++ b/ziti/cmd/demo/root.go @@ -72,6 +72,10 @@ func NewDemoCmd(p common.OptionsProvider) *cobra.Command { demoCmd.AddCommand(newEchoServerCmd()) demoCmd.AddCommand(newZcatCmd()) + + zcatCloseTestCmd := newZcatCloseTestCmd() + zcatCloseTestCmd.Hidden = true + demoCmd.AddCommand(zcatCloseTestCmd) demoCmd.AddCommand(agentCmd) demoCmd.AddCommand(setupCmd) diff --git a/ziti/cmd/demo/zcat_closetest.go b/ziti/cmd/demo/zcat_closetest.go new file mode 100644 index 000000000..e8e650969 --- /dev/null +++ b/ziti/cmd/demo/zcat_closetest.go @@ -0,0 +1,163 @@ +/* + Copyright NetFoundry Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package demo + +import ( + "bufio" + "fmt" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/foundation/v2/debugz" + "github.com/openziti/sdk-golang/ziti" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "net" + "os" + "strings" + "time" +) + +type zcatCloseTestAction struct { + verbose bool + logFormatter string + configFile string +} + +func newZcatCloseTestCmd() *cobra.Command { + action := &zcatCloseTestAction{} + + cmd := &cobra.Command{ + Use: "zcatCloseTest ", + Example: "ziti demo zcatCloseTest tcp:localhost:1234 or ziti demo zcatCloseTest -i zcatCloseTest.json ziti:echo", + Short: "A simple network cat facility which can run over tcp or ziti", + Args: cobra.ExactArgs(1), + Run: action.run, + } + + // allow interspersing positional args and flags + cmd.Flags().SetInterspersed(true) + cmd.Flags().BoolVarP(&action.verbose, "verbose", "v", false, "Enable verbose logging") + cmd.Flags().StringVar(&action.logFormatter, "log-formatter", "", "Specify log formatter [json|pfxlog|text]") + cmd.Flags().StringVarP(&action.configFile, "identity", "i", "", "Specify the Ziti identity to use. If not specified the Ziti listener won't be started") + cmd.Flags().SetInterspersed(true) + + return cmd +} + +func (self *zcatCloseTestAction) initLogging() { + logLevel := logrus.InfoLevel + if self.verbose { + logLevel = logrus.DebugLevel + } + + options := pfxlog.DefaultOptions().SetTrimPrefix("github.com/openziti/").NoColor() + pfxlog.GlobalInit(logLevel, options) + + switch self.logFormatter { + case "pfxlog": + pfxlog.SetFormatter(pfxlog.NewFormatter(pfxlog.DefaultOptions().SetTrimPrefix("github.com/openziti/").StartingToday())) + case "json": + pfxlog.SetFormatter(&logrus.JSONFormatter{TimestampFormat: "2006-01-02T15:04:05.000Z"}) + case "text": + pfxlog.SetFormatter(&logrus.TextFormatter{}) + default: + // let logrus do its own thing + } +} + +func (self *zcatCloseTestAction) run(_ *cobra.Command, args []string) { + self.initLogging() + + log := pfxlog.Logger() + + parts := strings.Split(args[0], ":") + if len(parts) < 2 { + log.Fatalf("destination %v is invalid. destination must be of the form network:address", args[0]) + } + network := parts[0] + addr := strings.Join(parts[1:], ":") + + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + line := scanner.Text() + if strings.HasPrefix(line, "stack") { + debugz.DumpStack() + fmt.Println("===============================================================") + } else { + if err := self.sendRecv(network, addr, scanner.Text()); err != nil { + panic(err) + } + } + } +} + +func (self *zcatCloseTestAction) sendRecv(network, addr, line string) error { + log := pfxlog.Logger() + + var conn net.Conn + var err error + + log.Debugf("dialing %v:%v", network, addr) + if network == "tcp" || network == "udp" { + conn, err = net.Dial(network, addr) + } else if network == "ziti" { + zitiConfig, cfgErr := ziti.NewConfigFromFile(self.configFile) + if cfgErr != nil { + log.WithError(cfgErr).Fatalf("unable to load ziti identity from [%v]", self.configFile) + } + + dialIdentifier := "" + if atIdx := strings.IndexByte(addr, '@'); atIdx > 0 { + dialIdentifier = addr[:atIdx] + addr = addr[atIdx+1:] + } + + zitiContext, ctxErr := ziti.NewContext(zitiConfig) + if ctxErr != nil { + pfxlog.Logger().WithError(err).Fatal("could not create sdk context from config") + } + + defer func() { + zitiContext.Close() + }() + + dialOptions := &ziti.DialOptions{ + ConnectTimeout: 5 * time.Second, + Identity: dialIdentifier, + } + conn, err = zitiContext.DialWithOptions(addr, dialOptions) + } else { + log.Fatalf("invalid network '%v'. valid values are ['ziti', 'tcp', 'udp']", network) + } + + if err != nil { + log.WithError(err).Fatalf("unable to dial %v:%v", network, addr) + } + + log.Debugf("connected to %v:%v", network, addr) + + n, err := conn.Write([]byte(line)) + if err != nil { + return err + } + + buf := make([]byte, n) + if _, err = conn.Read(buf); err != nil { + return err + } + fmt.Println(string(buf)) + return nil +} diff --git a/ziti/cmd/fabric/validate_router_links.go b/ziti/cmd/fabric/validate_router_links.go index e7b6386b9..719bc561a 100644 --- a/ziti/cmd/fabric/validate_router_links.go +++ b/ziti/cmd/fabric/validate_router_links.go @@ -26,13 +26,13 @@ import ( "github.com/openziti/ziti/ziti/cmd/common" "github.com/spf13/cobra" "google.golang.org/protobuf/proto" + "os" "time" ) type validateRouterLinksAction struct { api.Options - filter string - showOnlyInvalid bool + includeValid bool eventNotify chan *mgmt_pb.RouterLinkDetails } @@ -45,20 +45,19 @@ func NewValidateRouterLinksCmd(p common.OptionsProvider) *cobra.Command { } validateLinksCmd := &cobra.Command{ - Use: "router-links", + Use: "router-links ", Short: "Validate router links", - Example: "ziti fabric validate router-links --filter 'name=\"my-router\"' --show-only-invalid", - Args: cobra.ExactArgs(0), + Example: "ziti fabric validate router-links --filter 'name=\"my-router\"' --include-valid", + Args: cobra.MaximumNArgs(1), RunE: action.validateRouterLinks, } action.AddCommonFlags(validateLinksCmd) - validateLinksCmd.Flags().BoolVar(&action.showOnlyInvalid, "show-only-invalid", false, "Hide results for valid Links") - validateLinksCmd.Flags().StringVar(&action.filter, "filter", "", "Specify for which routers to validate links") + validateLinksCmd.Flags().BoolVar(&action.includeValid, "include-valid", false, "Don't hide results for valid links") return validateLinksCmd } -func (self *validateRouterLinksAction) validateRouterLinks(cmd *cobra.Command, _ []string) error { +func (self *validateRouterLinksAction) validateRouterLinks(_ *cobra.Command, args []string) error { closeNotify := make(chan struct{}) self.eventNotify = make(chan *mgmt_pb.RouterLinkDetails, 1) @@ -75,8 +74,13 @@ func (self *validateRouterLinksAction) validateRouterLinks(cmd *cobra.Command, _ return err } + filter := "" + if len(args) > 0 { + filter = args[0] + } + request := &mgmt_pb.ValidateRouterLinksRequest{ - Filter: self.filter, + Filter: filter, } responseMsg, err := protobufs.MarshalTyped(request).WithTimeout(time.Duration(self.Timeout) * time.Second).SendForReply(ch) @@ -94,6 +98,7 @@ func (self *validateRouterLinksAction) validateRouterLinks(cmd *cobra.Command, _ expected := response.RouterCount + errCount := 0 for expected > 0 { select { case <-closeNotify: @@ -103,19 +108,28 @@ func (self *validateRouterLinksAction) validateRouterLinks(cmd *cobra.Command, _ result := "validation successful" if !routerDetail.ValidateSuccess { result = fmt.Sprintf("error: unable to validation (%s)", routerDetail.Message) + errCount++ } fmt.Printf("routerId: %s, routerName: %v, links: %v, %s\n", routerDetail.RouterId, routerDetail.RouterName, len(routerDetail.LinkDetails), result) for _, linkDetail := range routerDetail.LinkDetails { - if !self.showOnlyInvalid || !linkDetail.IsValid { - fmt.Printf("\tlinkId: %s, destConnected: %v, ctrlState: %v, routerState: %v\n", - linkDetail.LinkId, linkDetail.DestConnected, linkDetail.CtrlState, linkDetail.RouterState.String()) + if self.includeValid || !linkDetail.IsValid { + fmt.Printf("\tlinkId: %s, destConnected: %v, ctrlState: %v, routerState: %v, dest: %v, dialed: %v \n", + linkDetail.LinkId, linkDetail.DestConnected, linkDetail.CtrlState, linkDetail.RouterState.String(), + linkDetail.DestRouterId, linkDetail.Dialed) + } + if !linkDetail.IsValid { + errCount++ } } expected-- } } + fmt.Printf("%v errors found\n", errCount) + if errCount > 0 { + os.Exit(1) + } return nil } diff --git a/zititest/go.mod b/zititest/go.mod index ecac925d0..8bb9d6a61 100644 --- a/zititest/go.mod +++ b/zititest/go.mod @@ -11,13 +11,13 @@ require ( github.com/google/uuid v1.5.0 github.com/michaelquigley/pfxlog v0.6.10 github.com/openziti/agent v1.0.16 - github.com/openziti/channel/v2 v2.0.113 - github.com/openziti/fablab v0.5.32 - github.com/openziti/foundation/v2 v2.0.35 - github.com/openziti/identity v1.0.68 - github.com/openziti/sdk-golang v0.22.6 - github.com/openziti/storage v0.2.27 - github.com/openziti/transport/v2 v2.0.119 + github.com/openziti/channel/v2 v2.0.116 + github.com/openziti/fablab v0.5.38 + github.com/openziti/foundation/v2 v2.0.36 + github.com/openziti/identity v1.0.69 + github.com/openziti/sdk-golang v0.22.17 + github.com/openziti/storage v0.2.28 + github.com/openziti/transport/v2 v2.0.121 github.com/openziti/ziti v0.28.3 github.com/pkg/errors v0.9.1 github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 @@ -25,7 +25,7 @@ require ( github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.8.4 go.etcd.io/bbolt v1.3.8 - golang.org/x/net v0.19.0 + golang.org/x/net v0.20.0 google.golang.org/protobuf v1.32.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -38,9 +38,10 @@ require ( github.com/alecthomas/chroma v0.10.0 // indirect github.com/andybalholm/brotli v1.0.6 // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect + github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go v1.47.10 // indirect + github.com/aws/aws-sdk-go v1.49.2 // indirect github.com/biogo/store v0.0.0-20200525035639-8c94ae1e7c9c // indirect github.com/blang/semver v3.5.1+incompatible // indirect github.com/boltdb/bolt v1.3.1 // indirect @@ -65,13 +66,13 @@ require ( github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect - github.com/go-openapi/analysis v0.22.1 // indirect + github.com/go-openapi/analysis v0.22.2 // indirect github.com/go-openapi/errors v0.21.0 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/loads v0.21.5 // indirect github.com/go-openapi/runtime v0.26.2 // indirect - github.com/go-openapi/spec v0.20.13 // indirect + github.com/go-openapi/spec v0.20.14 // indirect github.com/go-openapi/strfmt v0.22.0 // indirect github.com/go-openapi/swag v0.22.7 // indirect github.com/go-openapi/validate v0.22.6 // indirect @@ -81,8 +82,8 @@ require ( github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 // indirect github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/mux v1.8.1 // indirect - github.com/gorilla/schema v1.2.1 // indirect - github.com/gorilla/securecookie v1.1.2 // indirect + github.com/gorilla/schema v1.2.0 // indirect + github.com/gorilla/securecookie v1.1.1 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/hashicorp/go-hclog v1.6.2 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect @@ -94,8 +95,10 @@ require ( github.com/hashicorp/raft v1.6.0 // indirect github.com/hashicorp/raft-boltdb v0.0.0-20220329195025-15018e9b97e0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/influxdata/influxdb-client-go/v2 v2.13.0 // indirect github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d // indirect - github.com/jedib0t/go-pretty/v6 v6.4.9 // indirect + github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect + github.com/jedib0t/go-pretty/v6 v6.5.3 // indirect github.com/jessevdk/go-flags v1.5.0 // indirect github.com/jinzhu/copier v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect @@ -126,15 +129,16 @@ require ( github.com/muhlemmer/httpforwarded v0.1.0 // indirect github.com/natefinch/lumberjack v2.0.0+incompatible // indirect github.com/natefinch/npipe v0.0.0-20160621034901-c1b8fa8bdcce // indirect + github.com/oapi-codegen/runtime v1.0.0 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openziti/dilithium v0.3.3 // indirect - github.com/openziti/edge-api v0.26.7 // indirect + github.com/openziti/edge-api v0.26.8 // indirect github.com/openziti/jwks v1.0.3 // indirect - github.com/openziti/metrics v1.2.41 // indirect - github.com/openziti/runzmd v1.0.36 // indirect - github.com/openziti/secretstream v0.1.15 // indirect + github.com/openziti/metrics v1.2.43 // indirect + github.com/openziti/runzmd v1.0.37 // indirect + github.com/openziti/secretstream v0.1.16 // indirect github.com/openziti/x509-claims v1.0.3 // indirect github.com/openziti/xweb/v2 v2.1.0 // indirect github.com/openziti/ziti-db-explorer v1.1.3 // indirect @@ -163,8 +167,8 @@ require ( github.com/spf13/viper v1.18.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect - github.com/tklauser/go-sysconf v0.3.13 // indirect - github.com/tklauser/numcpus v0.7.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect @@ -180,14 +184,14 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect go4.org v0.0.0-20180809161055-417644f6feb5 // indirect - golang.org/x/crypto v0.17.0 // indirect - golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect + golang.org/x/crypto v0.18.0 // indirect + golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/image v0.13.0 // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/oauth2 v0.15.0 // indirect + golang.org/x/oauth2 v0.16.0 // indirect golang.org/x/sync v0.5.0 // indirect - golang.org/x/sys v0.15.0 // indirect - golang.org/x/term v0.15.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/term v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.16.0 // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/zititest/go.sum b/zititest/go.sum index 87a25db13..77e7fc6ca 100644 --- a/zititest/go.sum +++ b/zititest/go.sum @@ -65,6 +65,7 @@ github.com/MichaelMure/go-term-text v0.3.1/go.mod h1:QgVjAEDUnRMlzpS6ky5CGblux7e github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw= github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI= github.com/alecthomas/chroma v0.7.1/go.mod h1:gHw09mkX1Qp80JlYbmN9L3+4R5o6DJJ3GRShh+AICNc= github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek= @@ -82,6 +83,8 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= +github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= +github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= @@ -91,8 +94,8 @@ github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/aws/aws-sdk-go v1.47.10 h1:cvufN7WkD1nlOgpRopsmxKQlFp5X1MfyAw4r7BBORQc= -github.com/aws/aws-sdk-go v1.47.10/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.49.2 h1:+4BEcm1nPCoDbVd+gg8cdxpa1qJfrvnddy12vpEVWjw= +github.com/aws/aws-sdk-go v1.49.2/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -103,6 +106,7 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= @@ -217,8 +221,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -github.com/go-openapi/analysis v0.22.1 h1:nBWSKtx/OQr6FADwy0AYDZFdT05Abv5eYWECByHEQMg= -github.com/go-openapi/analysis v0.22.1/go.mod h1:acDnkkCI2QxIo8sSIPgmp1wUlRohV7vfGtAIVae73b0= +github.com/go-openapi/analysis v0.22.2 h1:ZBmNoP2h5omLKr/srIC9bfqrUGzT6g6gNv03HE9Vpj0= +github.com/go-openapi/analysis v0.22.2/go.mod h1:pDF4UbZsQTo/oNuRfAWWd4dAh4yuYf//LYorPTjrpvo= github.com/go-openapi/errors v0.21.0 h1:FhChC/duCnfoLj1gZ0BgaBmzhJC2SL/sJr8a2vAobSY= github.com/go-openapi/errors v0.21.0/go.mod h1:jxNTMUxRCKj65yb/okJGEtahVd7uvWnuWfj53bse4ho= github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= @@ -229,8 +233,8 @@ github.com/go-openapi/loads v0.21.5 h1:jDzF4dSoHw6ZFADCGltDb2lE4F6De7aWSpe+IcsRz github.com/go-openapi/loads v0.21.5/go.mod h1:PxTsnFBoBe+z89riT+wYt3prmSBP6GDAQh2l9H1Flz8= github.com/go-openapi/runtime v0.26.2 h1:elWyB9MacRzvIVgAZCBJmqTi7hBzU0hlKD4IvfX0Zl0= github.com/go-openapi/runtime v0.26.2/go.mod h1:O034jyRZ557uJKzngbMDJXkcKJVzXJiymdSfgejrcRw= -github.com/go-openapi/spec v0.20.13 h1:XJDIN+dLH6vqXgafnl5SUIMnzaChQ6QTo0/UPMbkIaE= -github.com/go-openapi/spec v0.20.13/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw= +github.com/go-openapi/spec v0.20.14 h1:7CBlRnw+mtjFGlPDRZmAMnq35cRzI91xj03HVyUi/Do= +github.com/go-openapi/spec v0.20.14/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw= github.com/go-openapi/strfmt v0.22.0 h1:Ew9PnEYc246TwrEspvBdDHS4BVKXy/AOVsfqGDgAcaI= github.com/go-openapi/strfmt v0.22.0/go.mod h1:HzJ9kokGIju3/K6ap8jL+OlGAbjpSv27135Yr9OivU4= github.com/go-openapi/swag v0.22.7 h1:JWrc1uc/P9cSomxfnsFSVWoE1FW6bNbrVPmpQYpCcR8= @@ -307,8 +311,6 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -336,10 +338,10 @@ github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyE github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/schema v1.2.1 h1:tjDxcmdb+siIqkTNoV+qRH2mjYdr2hHe5MKXbp61ziM= -github.com/gorilla/schema v1.2.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= -github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= -github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= +github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc= +github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU= +github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= @@ -400,11 +402,14 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb-client-go/v2 v2.2.2/go.mod h1:fa/d1lAdUHxuc1jedx30ZfNG573oQTQmUni3N6pcW+0= +github.com/influxdata/influxdb-client-go/v2 v2.13.0 h1:ioBbLmR5NMbAjP4UVA5r9b5xGjpABD7j65pI8kFphDM= +github.com/influxdata/influxdb-client-go/v2 v2.13.0/go.mod h1:k+spCbt9hcvqvUiz0sr5D8LolXHqAAOfPw9v/RIRHl4= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d h1:/WZQPMZNsjZ7IlCpsLGdQBINg5bxKQ1K1sh6awxLtkA= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU= github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/jedib0t/go-pretty/v6 v6.4.9 h1:vZ6bjGg2eBSrJn365qlxGcaWu09Id+LHtrfDWlB2Usc= -github.com/jedib0t/go-pretty/v6 v6.4.9/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs= +github.com/jedib0t/go-pretty/v6 v6.5.3 h1:GIXn6Er/anHTkVUoufs7ptEvxdD6KIhR7Axa2wYCPF0= +github.com/jedib0t/go-pretty/v6 v6.5.3/go.mod h1:5LQIxa52oJ/DlDSLv0HEkWOFMDGoWkJb9ss5KqPpJBg= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc= github.com/jeremija/gosubmit v0.2.7/go.mod h1:Ui+HS073lCFREXBbdfrJzMB57OI/bdxTiLtrDHHhFPI= @@ -427,6 +432,7 @@ github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kataras/go-events v0.0.3 h1:o5YK53uURXtrlg7qE/vovxd/yKOJcLuFtPQbf1rYMC4= github.com/kataras/go-events v0.0.3/go.mod h1:bFBgtzwwzrag7kQmGuU1ZaVxhK2qseYPQomXoVEMsj4= @@ -503,7 +509,6 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI= @@ -560,6 +565,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oapi-codegen/runtime v1.0.0 h1:P4rqFX5fMFWqRzY9M/3YF9+aPSPPB06IzP2P7oOxrWo= +github.com/oapi-codegen/runtime v1.0.0/go.mod h1:LmCUMQuPB4M/nLXilQXhHw+BLZdDb18B34OO356yJ/A= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 h1:Yl0tPBa8QPjGmesFh1D0rDy+q1Twx6FyU7VWHi8wZbI= @@ -580,32 +587,32 @@ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYr github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openziti/agent v1.0.16 h1:9Saji+8hFE1NpzP2XzDhsVJbCrDlhixoLHfOpFt5Z+U= github.com/openziti/agent v1.0.16/go.mod h1:zfm53+PVWoGFzjGGgQdKby5749G6VRYHe+eQJmoVKy4= -github.com/openziti/channel/v2 v2.0.113 h1:J7GdiwusrwpHtbQKAgQErRe4RJdeqTUQhIZNgsZpDn4= -github.com/openziti/channel/v2 v2.0.113/go.mod h1:1cVOKm52klHza4WxRgcT4Ec/NlFrGwjXPZt/V7bSE+o= +github.com/openziti/channel/v2 v2.0.116 h1:VUxJ3rICTQz9fmSz6tbssC2tzXafL1MAY6yvgHfSUHI= +github.com/openziti/channel/v2 v2.0.116/go.mod h1:RADBBOkbwpFMmbznU3bZmUsBB646seqZnQ7GPI6Chjg= github.com/openziti/dilithium v0.3.3 h1:PLgQ6PMNLSTzCFbX/h98cmudgz/cU6TmjdSv5NAPD8k= github.com/openziti/dilithium v0.3.3/go.mod h1:vsCjI2AU/hon9e+dLhUFbCNGesJDj2ASgkySOcpmvjo= -github.com/openziti/edge-api v0.26.7 h1:dHLH7+O+Yp3HPmhgAbvq8z93EcZDypiSOHm/PVVUCoc= -github.com/openziti/edge-api v0.26.7/go.mod h1:yKQYyc3zhHRM7Y2BRd5R7gT9zelh46julW4chjv2W9I= -github.com/openziti/fablab v0.5.32 h1:F2n3m+EZ9ulXUnnox2x6SjsuYQkuNnSao62FaLhLSUA= -github.com/openziti/fablab v0.5.32/go.mod h1:qgW8yiZ7lXuE0FZ85pL4t4ohD5JAnNU1r4EdGLs2TM4= -github.com/openziti/foundation/v2 v2.0.35 h1:4VaMwZ2kAy6jwBYeQIBN2m8rcGroTDX4A2Jp7NAKb6M= -github.com/openziti/foundation/v2 v2.0.35/go.mod h1:Xnb3IxP1e1UcgLggqSunEpCjH3iHozkPi9Bd9GESbwo= -github.com/openziti/identity v1.0.68 h1:SaFr7BeFQBoWQDiT28vUb8D9w7v6lIAK6/9RkwmV0OU= -github.com/openziti/identity v1.0.68/go.mod h1:HbOu3TQ032v8xE6xZWjO51azF4fUxRLjO/l/oGqJwUI= +github.com/openziti/edge-api v0.26.8 h1:W1iHwVrb4hVKXWhfN8g/dl1d0RGdus6nOYbhM5ixOEg= +github.com/openziti/edge-api v0.26.8/go.mod h1:Tm2Qn1BC0zF+F261Y8FTyPtS/UkeUtUBYoT6ueCjVbA= +github.com/openziti/fablab v0.5.38 h1:G8ieax/d4LGeRPuMT2XHTOc18jtZTaXtPmjA+5CVO3U= +github.com/openziti/fablab v0.5.38/go.mod h1:LstfQixYgv82aUBR8ranX2Hc9KHohFC1G5/AeaeTMwg= +github.com/openziti/foundation/v2 v2.0.36 h1:ogEIvsWur8/9mUzf9NOB4hRUyx372Uy6AmnHRcurIkY= +github.com/openziti/foundation/v2 v2.0.36/go.mod h1:MdK2oAJSwo7iCfvVdG16ZGz47qP7nG97ovnqEdXW2kQ= +github.com/openziti/identity v1.0.69 h1:wNgQomnv8ar2S1wge9jQK1jpqE2virOKKG8GyfTiHMQ= +github.com/openziti/identity v1.0.69/go.mod h1:+7hQNAG5nUUdz0165OubWpMHkP/ZVJB3nv9HUXXi9H8= github.com/openziti/jwks v1.0.3 h1:hf8wkb+Cg4nH/HM0KROFd7u+C3DkRVcFZJ7tDV+4icc= github.com/openziti/jwks v1.0.3/go.mod h1:t4xxq8vlXGsPn29kiQVnZBBDDnEoOFqtJoHibkJunQQ= -github.com/openziti/metrics v1.2.41 h1:JShcFb6qJPA2cMiWQLtcSXiJjsrhEWpH+aVcjT/Mcbs= -github.com/openziti/metrics v1.2.41/go.mod h1:L9h0NrliMA3+p7+ascKgvx28qoKHymN9l+CMA+Q+sZc= -github.com/openziti/runzmd v1.0.36 h1:HOqTZFzTTFu52qmCAQfFvKDmCSl8ZqP1PQQ0UnJIA4E= -github.com/openziti/runzmd v1.0.36/go.mod h1:jYqummjskmFh63htJFF2SrUuvxNQifqd5REUhYVaY/A= -github.com/openziti/sdk-golang v0.22.6 h1:AG0FNnh3QHTmqgL7Igl+ib2V65h0I2GskZ4Xi97eOo8= -github.com/openziti/sdk-golang v0.22.6/go.mod h1:eq0Ww3cX8SVUyhAVGlZSZPIGBrMEnUioVBRME/IZ7rU= -github.com/openziti/secretstream v0.1.15 h1:bGoPlT5zmZ+BiLKFMlaARG3gfiUzuhX/kmK6OInaghU= -github.com/openziti/secretstream v0.1.15/go.mod h1:LyghB5JOlgvFASkLYPiBgjj5rcFXKiLD4qwHYRfBxnU= -github.com/openziti/storage v0.2.27 h1:WdFD0KxXZxSoWOaojdi5r1LO0BTvn4x/7wwdwhRPssc= -github.com/openziti/storage v0.2.27/go.mod h1:p/04So5E3NT2jsGew0AS4hYTfP5srti3VytOjlVcx0M= -github.com/openziti/transport/v2 v2.0.119 h1:KOgHU+9EZUVPvv8ncifqHmNEcFUHbJHigo3jyPvWnOc= -github.com/openziti/transport/v2 v2.0.119/go.mod h1:H2IIBP6ed9isE/eJHGXtAZL0d73ApYOpLG9sSvutNNI= +github.com/openziti/metrics v1.2.43 h1:DSrmpLhoA45DlLVNdKOn2lBfCM0/r6wKz+3SDXe8X7Y= +github.com/openziti/metrics v1.2.43/go.mod h1:+RY4avT60Vbxb9wyfvRD0msrARyYCB5+heb8VIZzCm8= +github.com/openziti/runzmd v1.0.37 h1:qj2r9z4t7OAdmIXMdGbP9Su6TqA0bLdD2RMjJ71LRS0= +github.com/openziti/runzmd v1.0.37/go.mod h1:eKhqJsGoLeDHex/o5Mw6TcNJxlVljafSVm7ZU+bX5G8= +github.com/openziti/sdk-golang v0.22.17 h1:taywYpWpWBtZUj6KewMScYXgPe8TWz2nWNl96/y/IZ4= +github.com/openziti/sdk-golang v0.22.17/go.mod h1:t0sT5N1Q/LdAd54Dxz274sQ9vJo8/B5Q0jn+VZ9vFuw= +github.com/openziti/secretstream v0.1.16 h1:tVanF7OpJL1MJ1gvWaRlR2i+kAbrGsxr3q6EXFOS08U= +github.com/openziti/secretstream v0.1.16/go.mod h1:bvjGBUW/0e5MzD5S3FW3rhGASRNWAi+kTkTENZ9qRDE= +github.com/openziti/storage v0.2.28 h1:qHnsSF4RgQpT23hOXlwkAvJ0gO5PLmvTqyBy13dm3Rc= +github.com/openziti/storage v0.2.28/go.mod h1:ahdvsmmdQWFsZXeExvXeA8MHUXPLrwuDFBJDTztLY5E= +github.com/openziti/transport/v2 v2.0.121 h1:9WB1/9YMFed2UuefqZq+odUYYkoFOr+8aBIAZEC1MNE= +github.com/openziti/transport/v2 v2.0.121/go.mod h1:hS7TzoyTIwm4lVEsGyjQkoEg+vA+6dAOR8S4FZmWIj4= github.com/openziti/x509-claims v1.0.3 h1:HNdQ8Nf1agB3lBs1gahcO6zfkeS4S5xoQ2/PkY4HRX0= github.com/openziti/x509-claims v1.0.3/go.mod h1:Z0WIpBm6c4ecrpRKrou6Gk2wrLWxJO/+tuUwKh8VewE= github.com/openziti/xweb/v2 v2.1.0 h1:Xhh3C2pZkq/Prr65V+SfFSibLDYteoc4f62KQCcTZF4= @@ -628,7 +635,6 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= -github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= @@ -761,6 +767,7 @@ github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5q github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -776,7 +783,6 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -786,12 +792,10 @@ github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSW github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 h1:3SNcvBmEPE1YlB1JpVZouslJpI3GBNoiqW7+wb0Rz7w= github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= -github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4= -github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= -github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4= -github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= @@ -886,8 +890,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -898,8 +902,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM= -golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -987,8 +991,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1003,8 +1007,8 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1101,16 +1105,17 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/zititest/models/links-test/configs/router.yml.tmpl b/zititest/models/links-test/configs/router.yml.tmpl index 648219ce3..2e6a24f04 100644 --- a/zititest/models/links-test/configs/router.yml.tmpl +++ b/zititest/models/links-test/configs/router.yml.tmpl @@ -12,6 +12,9 @@ identity: key: /home/{{$ssh_username}}/fablab/cfg/{{$identity}}.key ca: /home/{{$ssh_username}}/fablab/cfg/{{$identity}}-server.chain.pem +tls: + handshakeTimeout: 30s + ctrl: endpoints: {{ range $host := .Model.MustSelectHosts "component.ctrl" 1 }} - tls:{{ $host.PublicIp }}:6262{{end}} @@ -36,6 +39,8 @@ link: advertise: tls:{{$router_ip}}:60{{printf "%02d" .Component.ScaleIndex }} dialers: - binding: transport + options: + connectTimeout: 30s listeners: {{if .Component.HasTag "tunneler"}} diff --git a/zititest/models/links-test/main.go b/zititest/models/links-test/main.go index 85a7d949f..a59fa8c76 100644 --- a/zititest/models/links-test/main.go +++ b/zititest/models/links-test/main.go @@ -3,6 +3,7 @@ package main import ( "embed" _ "embed" + "fmt" "github.com/openziti/fablab" "github.com/openziti/fablab/kernel/lib/actions" "github.com/openziti/fablab/kernel/lib/actions/component" @@ -21,9 +22,9 @@ import ( "github.com/openziti/ziti/zititest/models/test_resources" "github.com/openziti/ziti/zititest/zitilab" "github.com/openziti/ziti/zititest/zitilab/actions/edge" + "github.com/openziti/ziti/zititest/zitilab/chaos" "github.com/openziti/ziti/zititest/zitilab/models" "os" - "os/exec" "path" "time" ) @@ -201,8 +202,9 @@ var m = &model.Model{ "bootstrap": model.ActionBinder(func(m *model.Model) model.Action { workflow := actions.Workflow() + workflow.AddAction(host.GroupExec("*", 50, "touch .hushlogin")) workflow.AddAction(component.Stop(".ctrl")) - workflow.AddAction(host.GroupExec("*", 25, "rm -f logs/*")) + workflow.AddAction(host.GroupExec("*", 50, "rm -f logs/*")) workflow.AddAction(host.GroupExec("component.ctrl", 5, "rm -rf ./fablab/ctrldata")) workflow.AddAction(component.Start(".ctrl")) @@ -214,30 +216,19 @@ var m = &model.Model{ workflow.AddAction(edge.Login("#ctrl1")) - workflow.AddAction(component.StopInParallel(models.RouterTag, 25)) + workflow.AddAction(component.StopInParallel(models.RouterTag, 50)) workflow.AddAction(edge.InitEdgeRouters(models.RouterTag, 2)) return workflow }), - "stop": model.Bind(component.StopInParallelHostExclusive("*", 15)), "clean": model.Bind(actions.Workflow( component.StopInParallelHostExclusive("*", 15), host.GroupExec("*", 25, "rm -f logs/*"), )), - "login": model.Bind(edge.Login("#ctrl1")), - "login2": model.Bind(edge.Login("#ctrl2")), - "login3": model.Bind(edge.Login("#ctrl3")), - "refreshCtrlZiti": model.ActionBinder(func(m *model.Model) model.Action { - return model.ActionFunc(func(run model.Run) error { - zitiPath, err := exec.LookPath("ziti") - if err != nil { - return err - } - - deferred := rsync.NewRsyncHost("ctrl", zitiPath, "/home/ubuntu/fablab/bin/ziti") - return deferred.Execute(run) - }) - }), + "login": model.Bind(edge.Login("#ctrl1")), + "login2": model.Bind(edge.Login("#ctrl2")), + "login3": model.Bind(edge.Login("#ctrl3")), + "sowChaos": model.Bind(model.ActionFunc(sowChaos)), }, Infrastructure: model.Stages{ @@ -261,6 +252,20 @@ var m = &model.Model{ }, } +func sowChaos(run model.Run) error { + controllers, err := chaos.SelectRandom(run, ".ctrl", chaos.RandomOfTotal()) + if err != nil { + return err + } + routers, err := chaos.SelectRandom(run, ".router", chaos.Percentage(15)) + if err != nil { + return err + } + toRestart := append(routers, controllers...) + fmt.Printf("restarting %v controllers and %v routers\n", len(controllers), len(routers)) + return chaos.RestartSelected(run, toRestart, 50) +} + func main() { m.AddActivationActions("stop", "bootstrap") diff --git a/zititest/zitilab/actions/consul.go b/zititest/zitilab/actions/consul.go deleted file mode 100644 index 883ef89a4..000000000 --- a/zititest/zitilab/actions/consul.go +++ /dev/null @@ -1,41 +0,0 @@ -package zitilib_actions - -import ( - "fmt" - "github.com/openziti/fablab/kernel/libssh" - - "github.com/openziti/fablab/kernel/model" - "github.com/sirupsen/logrus" -) - -type consulStart struct { - hostSpec string - consulServer string - configDir string - dataPath string - logFile string -} - -func StartConsul(hostSpec, consulServer, configDir, dataPath, logFile string) model.Action { - return &consulStart{ - hostSpec: hostSpec, - consulServer: consulServer, - configDir: configDir, - dataPath: dataPath, - logFile: logFile, - } -} - -func (cs *consulStart) Execute(run model.Run) error { - return run.GetModel().ForEachHost(cs.hostSpec, 24, func(host *model.Host) error { - ssh := host.NewSshConfigFactory() - - cmd := fmt.Sprintf("screen -d -m nohup consul agent -join %s -config-dir %s -data-dir %s -log-file %s 2>&1 &", cs.consulServer, cs.configDir, cs.dataPath, cs.logFile) - - if output, err := libssh.RemoteExec(ssh, cmd); err != nil { - logrus.Errorf("error starting consul service [%s] (%v)", output, err) - return err - } - return nil - }) -} diff --git a/zititest/zitilab/chaos/chaos.go b/zititest/zitilab/chaos/chaos.go new file mode 100644 index 000000000..524a8559d --- /dev/null +++ b/zititest/zitilab/chaos/chaos.go @@ -0,0 +1,75 @@ +/* + Copyright NetFoundry Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package chaos + +import ( + "fmt" + "github.com/openziti/fablab/kernel/model" + "math/rand" +) + +func StaticNumber(val int) func(int) int { + return func(int) int { + return val + } +} +func RandomOfTotal() func(count int) int { + return func(count int) int { + return rand.Intn(count) + 1 + } +} + +func Percentage(pct uint8) func(count int) int { + adjustedPct := float64(pct) / 100 + return func(count int) int { + return int(float64(count) * adjustedPct) + } +} + +func SelectRandom(run model.Run, selector string, f func(count int) int) ([]*model.Component, error) { + list := run.GetModel().SelectComponents(selector) + toSelect := f(len(list)) + + if toSelect < 1 { + return nil, nil + } + + rand.Shuffle(len(list), func(i, j int) { + list[i], list[j] = list[j], list[i] + }) + + var result []*model.Component + for i := 0; i < len(list) && i < toSelect; i++ { + result = append(result, list[i]) + } + return result, nil +} + +func RestartSelected(run model.Run, list []*model.Component, concurrency int) error { + if len(list) == 0 { + return nil + } + return run.GetModel().ForEachComponentIn(list, concurrency, func(c *model.Component) error { + if sc, ok := c.Type.(model.ServerComponent); ok { + if err := c.Type.Stop(run, c); err != nil { + return err + } + return sc.Start(run, c) + } + return fmt.Errorf("component %v isn't of ServerComponent type, is of type %T", c, c.Type) + }) +} diff --git a/zititest/zitilab/component_common.go b/zititest/zitilab/component_common.go index fde736691..e33031a35 100644 --- a/zititest/zitilab/component_common.go +++ b/zititest/zitilab/component_common.go @@ -29,7 +29,7 @@ func getZitiProcessFilter(c *model.Component, zitiType string) func(string) bool return func(s string) bool { return strings.Contains(s, "ziti") && strings.Contains(s, zitiType) && - strings.Contains(s, fmt.Sprintf("--cli-agent-alias %s", c.Id)) && + strings.Contains(s, fmt.Sprintf("--cli-agent-alias %s ", c.Id)) && !strings.Contains(s, "sudo ") } } @@ -46,8 +46,8 @@ func startZitiComponent(c *model.Component, zitiType string, version string, con useSudo = "sudo" } - serviceCmd := fmt.Sprintf("nohup %s %s %s run --log-formatter pfxlog %s --cli-agent-alias %s > %s 2>&1 &", - useSudo, binaryPath, zitiType, configPath, c.Id, logsPath) + serviceCmd := fmt.Sprintf("nohup %s %s %s run --cli-agent-alias %s --log-formatter pfxlog %s > %s 2>&1 &", + useSudo, binaryPath, zitiType, c.Id, configPath, logsPath) logrus.Info(serviceCmd) value, err := c.GetHost().ExecLogged(serviceCmd) if err != nil { diff --git a/zititest/zitilab/component_router.go b/zititest/zitilab/component_router.go index 6b4cafd81..3b0ba2226 100644 --- a/zititest/zitilab/component_router.go +++ b/zititest/zitilab/component_router.go @@ -116,7 +116,15 @@ func (self *RouterType) IsRunning(_ model.Run, c *model.Component) (bool, error) return len(pids) > 0, nil } -func (self *RouterType) Start(_ model.Run, c *model.Component) error { +func (self *RouterType) Start(r model.Run, c *model.Component) error { + isRunninng, err := self.IsRunning(r, c) + if err != nil { + return err + } + if isRunninng { + fmt.Printf("router %s already started\n", c.Id) + return nil + } return startZitiComponent(c, "router", self.Version, self.getConfigName(c)) }