diff --git a/controller/env/appenv.go b/controller/env/appenv.go index bbe5d9e69..f862f6597 100644 --- a/controller/env/appenv.go +++ b/controller/env/appenv.go @@ -118,7 +118,7 @@ func (ae *AppEnv) GetEnrollRegistry() model.EnrollmentRegistry { } func (ae *AppEnv) IsEdgeRouterOnline(id string) bool { - return ae.Broker.GetOnlineEdgeRouter(id) != nil + return ae.Broker.IsEdgeRouterOnline(id) } func (ae *AppEnv) GetApiClientCsrSigner() cert.Signer { diff --git a/controller/env/broker.go b/controller/env/broker.go index cae288431..c6df7026c 100644 --- a/controller/env/broker.go +++ b/controller/env/broker.go @@ -17,22 +17,14 @@ package env import ( - "fmt" - "github.com/golang/protobuf/proto" "github.com/kataras/go-events" "github.com/michaelquigley/pfxlog" - "github.com/openziti/edge/build" "github.com/openziti/edge/controller/model" "github.com/openziti/edge/controller/persistence" "github.com/openziti/edge/pb/edge_ctrl_pb" "github.com/openziti/fabric/controller/network" - "github.com/openziti/foundation/channel2" "github.com/openziti/foundation/storage/boltz" - "github.com/openziti/foundation/util/concurrenz" "go.etcd.io/bbolt" - "strings" - "sync" - "time" ) const ( @@ -44,382 +36,103 @@ const ( ApiSessionRemovedType = int32(edge_ctrl_pb.ContentType_ApiSessionRemovedType) ApiSessionAddedType = int32(edge_ctrl_pb.ContentType_ApiSessionAddedType) ApiSessionUpdatedType = int32(edge_ctrl_pb.ContentType_ApiSessionUpdatedType) + RequestClientReSyncType = int32(edge_ctrl_pb.ContentType_RequestClientReSyncType) ServerHelloType = int32(edge_ctrl_pb.ContentType_ServerHelloType) ClientHelloType = int32(edge_ctrl_pb.ContentType_ClientHelloType) ) -type edgeRouterMap struct { - internalMap *sync.Map //edgeRouterId -> edgeRouterEntry -} - -type edgeRouterEntry struct { - EdgeRouter *model.EdgeRouter - Channel channel2.Channel - send chan *channel2.Message - stop chan interface{} - running concurrenz.AtomicBoolean - stopping concurrenz.AtomicBoolean -} - -func newEdgeRouterEntry(router *model.EdgeRouter, ch channel2.Channel, sendBufferSize int) *edgeRouterEntry { - return &edgeRouterEntry{ - EdgeRouter: router, - Channel: ch, - send: make(chan *channel2.Message, sendBufferSize), - stop: make(chan interface{}, 0), - running: concurrenz.AtomicBoolean(0), - stopping: concurrenz.AtomicBoolean(0), - } -} - -func (entry *edgeRouterEntry) Start() { - - running := entry.running.Get() - if !running { - entry.running.Set(true) - go entry.run() - } -} - -func (entry *edgeRouterEntry) Stop() { - stopping := entry.stopping.Get() - if !stopping { - entry.stopping.Set(true) - go func() { - entry.stop <- struct{}{} - }() - } -} - -func (entry *edgeRouterEntry) run() { - for { - select { - case <-entry.stop: - entry.running.Set(false) - entry.stopping.Set(false) - return - case msg := <-entry.send: - if !entry.Channel.IsClosed() { - _ = entry.Channel.Send(msg) - } - } - } -} - -func (entry *edgeRouterEntry) Send(msg *channel2.Message) { - entry.send <- msg -} - -func (m *edgeRouterMap) AddEntry(edgeRouterEntry *edgeRouterEntry) { - m.internalMap.Store(edgeRouterEntry.EdgeRouter.Id, edgeRouterEntry) - edgeRouterEntry.Start() -} - -func (m *edgeRouterMap) GetEntry(edgeRouterId string) *edgeRouterEntry { - val, found := m.internalMap.Load(edgeRouterId) - if !found { - return nil - } - return val.(*edgeRouterEntry) -} - -func (m *edgeRouterMap) GetOnlineEntries() []*edgeRouterEntry { - var entries []*edgeRouterEntry - - m.internalMap.Range(func(_, vi interface{}) bool { - if entry, ok := vi.(*edgeRouterEntry); ok && !entry.Channel.IsClosed() { - entries = append(entries, entry) - } else { - panic("edge router map contains a non *edgeRouterEntry value") - } - - return true - }) - - return entries -} - -func (m *edgeRouterMap) RemoveEntry(edgeRouterId string) { - entry := m.GetEntry(edgeRouterId) - if entry != nil { - entry.Stop() - m.internalMap.Delete(edgeRouterId) - } -} - -func (m *edgeRouterMap) RangeEdgeRouterEntries(f func(entries *edgeRouterEntry) bool) { - m.internalMap.Range(func(edgeRouterId, value interface{}) bool { - if edgeRouterEntry, ok := value.(*edgeRouterEntry); ok { - return f(edgeRouterEntry) - } - pfxlog.Logger().Panic("could not convert edge router entry") - return false - }) -} - +// The Broker delegates Ziti Edge events to a RouterSyncStrategy. Handling the details of which events to watch +// and dealing with casting arguments to their proper concrete types. type Broker struct { ae *AppEnv events map[events.EventEmmiter]map[events.EventName][]events.Listener - edgeRouterMap *edgeRouterMap sessionChunkSize int apiSessionChunkSize int routerMsgBufferSize int + routerSyncStrategy RouterSyncStrategy } -func NewBroker(ae *AppEnv) *Broker { - b := &Broker{ - ae: ae, - edgeRouterMap: &edgeRouterMap{ - internalMap: &sync.Map{}, - }, +func NewBroker(ae *AppEnv, synchronizer RouterSyncStrategy) *Broker { + broker := &Broker{ + ae: ae, + routerSyncStrategy: synchronizer, sessionChunkSize: 100, apiSessionChunkSize: 100, routerMsgBufferSize: 100, } - b.events = map[events.EventEmmiter]map[events.EventName][]events.Listener{ - b.ae.GetStores().Session: { - boltz.EventDelete: []events.Listener{ - b.sessionDeleteEventHandler, - }, - boltz.EventCreate: []events.Listener{ - b.sessionCreateEventHandler, - }, - }, - b.ae.GetStores().ApiSession: { - boltz.EventCreate: []events.Listener{ - b.apiSessionCreateEventHandler, - }, - boltz.EventDelete: []events.Listener{ - b.apiSessionDeleteEventHandler, - }, - }, - b.ae.GetStores().ApiSessionCertificate: { - boltz.EventCreate: []events.Listener{ - b.apiSessionCertificateEventHandler, - }, - boltz.EventDelete: []events.Listener{ - b.apiSessionCertificateEventHandler, - }, - }, - } + broker.ae.GetStores().Session.AddListener(boltz.EventDelete, broker.sessionDeleted) + broker.ae.GetStores().Session.AddListener(boltz.EventCreate, broker.sessionCreated) + broker.ae.GetStores().ApiSession.AddListener(boltz.EventCreate, broker.apiSessionCreated) + broker.ae.GetStores().ApiSession.AddListener(boltz.EventDelete, broker.apiSessionDeleted) + broker.ae.GetStores().ApiSessionCertificate.AddListener(boltz.EventCreate, broker.apiSessionCertificateHandler) + broker.ae.GetStores().ApiSessionCertificate.AddListener(boltz.EventDelete, broker.apiSessionCertificateHandler) - b.registerEventHandlers() + ae.HostController.GetNetwork().AddRouterPresenceHandler(broker) - ae.HostController.GetNetwork().AddRouterPresenceHandler(b) - - return b + return broker } -func (b *Broker) AddEdgeRouter(ch channel2.Channel, edgeRouter *model.EdgeRouter) { - logger := pfxlog.Logger() - edgeRouterEntry := newEdgeRouterEntry(edgeRouter, ch, b.routerMsgBufferSize) - edgeRouterEntry.Start() - b.edgeRouterMap.AddEntry(edgeRouterEntry) - - //stream so we don't hold hundreds of thousands in memory at once - beforeFullStreamApiSessionTime := time.Now() - err := b.streamApiSessions(b.apiSessionChunkSize, func(addedMsg *edge_ctrl_pb.ApiSessionAdded) { - logger.Infof("sending edge router session updates [%d]", len(addedMsg.ApiSessions)) - - if buf, err := proto.Marshal(addedMsg); err == nil { - - beforeApiSessionSend := time.Now() - - msg := channel2.NewMessage(ApiSessionAddedType, buf) - edgeRouterEntry.Send(msg) - - apiSessionSendDelta := time.Now().Sub(beforeApiSessionSend) - logger.Debugf("broker api session send timing (micro-sec): %v\n", apiSessionSendDelta.Microseconds()) - } else { - logger.WithError(err).Error("error sending session added, could not marshal message content") +func (broker *Broker) RouterConnected(router *network.Router) { + go func() { + log := pfxlog.Logger().WithField("routerId", router.Id).WithField("routerName", router.Name).WithField("routerFingerprint", router.Fingerprint) + if router.Fingerprint != nil { + if edgeRouter, _ := broker.ae.Handlers.EdgeRouter.ReadOneByFingerprint(*router.Fingerprint); edgeRouter != nil { + pfxlog.Logger().WithField("routerId", router.Id). + WithField("routerName", router.Name). + WithField("routerFingerprint", router.Fingerprint). + Infof("broker detected edge router with id %s connecting", router.Id) + broker.routerSyncStrategy.RouterConnected(edgeRouter, router) + } else { + log.Debugf("broker detected non-edge router with id %s connecting", router.Id) + } } - }) - - fullStreamApiSessionDelta := time.Now().Sub(beforeFullStreamApiSessionTime) - logger.Debugf("broker api session FULL stream timing (micro-sec): %v\n", fullStreamApiSessionDelta.Microseconds()) - - if err != nil { - logger.WithError(err).Error("could not get stream sessions") - return - } - - beforeFullStreamSessionTime := time.Now() - err = b.streamSessions(edgeRouter.Id, b.sessionChunkSize, func(addedMsg *edge_ctrl_pb.SessionAdded) { - logger.Infof("sending edge router network session updates [%d]", len(addedMsg.Sessions)) - if buf, err := proto.Marshal(addedMsg); err == nil { - beforeSessionSend := time.Now() - - msg := channel2.NewMessage(SessionAddedType, buf) - edgeRouterEntry.Send(msg) - - sessionSendDelta := time.Now().Sub(beforeSessionSend) - logger.Debugf(fmt.Sprintf("broker session send timing (micro-sec): %v\n", sessionSendDelta.Microseconds())) - } else { - logger.WithError(err).Error("error sending network session added, could not marshal message content") - } - }) - fullStreamSessionTimeDelta := time.Now().Sub(beforeFullStreamSessionTime) - logger.Debugf(fmt.Sprintf("broker session FULL stream timing (micro-sec): %v\n", fullStreamSessionTimeDelta.Microseconds())) - - if err != nil { - logger.WithError(err).Errorf("could not stream current network sessions for edge router id [%s], connected but potentially out of sync", edgeRouter.Id) - return - } - logger.Infof("edge router connection finalized and synchronized [%s] [%s]", edgeRouter.Id, edgeRouter.Name) + }() } -func (b *Broker) apiSessionCreateEventHandler(args ...interface{}) { +func (broker *Broker) RouterDisconnected(r *network.Router) { + // if disconnected but, by id it is still connected then it may have been a dupe + // router connecting and being disconnected + if !broker.ae.HostController.GetNetwork().ConnectedRouter(r.Id) { + go func() { + pfxlog.Logger().WithField("routerId", r.Id). + WithField("routerName", r.Name). + WithField("routerFingerprint", r.Fingerprint). + Debugf("broker detected router with id %s disconnecting", r.Id) + broker.routerSyncStrategy.RouterDisconnected(r) + }() + } +} + +func (broker *Broker) apiSessionCreated(args ...interface{}) { var apiSession *persistence.ApiSession if len(args) == 1 { apiSession, _ = args[0].(*persistence.ApiSession) } if apiSession == nil { - log := pfxlog.Logger() - log.Error("could not cast event args to event details") + pfxlog.Logger().Error("during broker apiSessionCreated could not cast arg[0] to *persistence.ApiSession") return } - - b.sendApiSessionCreates(apiSession) + broker.routerSyncStrategy.ApiSessionAdded(apiSession) } -func (b *Broker) sendApiSessionCreates(apiSession *persistence.ApiSession) { - apiSessionMsg := &edge_ctrl_pb.ApiSessionAdded{} - - apiSessionMsg.IsFullState = false - - fingerprints, err := b.getFingerprints(apiSession.IdentityId, apiSession.Id) - if err != nil { - pfxlog.Logger().WithError(err).Errorf("could not get session fingerprints") - return - } - - if len(fingerprints) == 0 { - return - } - - apiSessionMsg.ApiSessions = append(apiSessionMsg.ApiSessions, &edge_ctrl_pb.ApiSession{ - Token: apiSession.Token, - CertFingerprints: fingerprints, - Id: apiSession.Id, - }) - - byteMsg, err := proto.Marshal(apiSessionMsg) - - if err != nil { - pfxlog.Logger().WithError(err).Errorf("could not marshal api session added message") - return - } - - channelMsg := channel2.NewMessage(ApiSessionAddedType, byteMsg) - - b.sendToAllEdgeRouters(channelMsg) -} - -// todo: use this once cert rolling happens -func (b *Broker) apiSessionUpdateEventHandler(args ...interface{}) { +func (broker *Broker) apiSessionDeleted(args ...interface{}) { var apiSession *persistence.ApiSession if len(args) == 1 { apiSession, _ = args[0].(*persistence.ApiSession) } if apiSession == nil { - log := pfxlog.Logger() - log.Error("could not cast event args to event details") + pfxlog.Logger().Error("during broker apiSessionDeleted could not cast arg[0] to *persistence.ApiSession") return } - b.sendApiSessionUpdates(apiSession) + broker.routerSyncStrategy.ApiSessionDeleted(apiSession) } -func (b *Broker) sendApiSessionUpdates(apiSession *persistence.ApiSession) { - apiSessionMsg := &edge_ctrl_pb.ApiSessionUpdated{} - - fingerprints, err := b.getFingerprints(apiSession.IdentityId, apiSession.Id) - if err != nil { - pfxlog.Logger().WithError(err).Errorf("could not get api session fingerprints") - return - } - - if len(fingerprints) == 0 { - pfxlog.Logger().WithError(err).Debug("api session has no fingerprints, not sending to edge routers") - return - } - - apiSessionMsg.ApiSessions = append(apiSessionMsg.ApiSessions, &edge_ctrl_pb.ApiSession{ - Token: apiSession.Token, - CertFingerprints: fingerprints, - Id: apiSession.Id, - }) - - byteMsg, err := proto.Marshal(apiSessionMsg) - - if err != nil { - pfxlog.Logger().WithError(err).Errorf("could not marshal api session updated message") - return - } - - channelMsg := channel2.NewMessage(ApiSessionUpdatedType, byteMsg) - - b.sendToAllEdgeRouters(channelMsg) -} - -func (b *Broker) sendToAllEdgeRouters(msg *channel2.Message) { - b.edgeRouterMap.RangeEdgeRouterEntries(func(edgeRouterEntry *edgeRouterEntry) bool { - edgeRouterEntry.Send(msg) - return true - }) -} - -func (b *Broker) sendToAllEdgeRoutersForSession(sessionId string, msg *channel2.Message) { - edgeRouterList, err := b.ae.Handlers.EdgeRouter.ListForSession(sessionId) - if err != nil { - pfxlog.Logger().WithError(err).Errorf("could not get edge routers for session [%s]", sessionId) - return - } - - for _, edgeRouter := range edgeRouterList.EdgeRouters { - edgeRouterEntry := b.edgeRouterMap.GetEntry(edgeRouter.Id) - if edgeRouterEntry != nil && !edgeRouterEntry.Channel.IsClosed() { - edgeRouterEntry.Send(msg) - } - } -} - -func (b *Broker) apiSessionDeleteEventHandler(args ...interface{}) { - var apiSession *persistence.ApiSession - if len(args) == 1 { - apiSession, _ = args[0].(*persistence.ApiSession) - } - - if apiSession == nil { - log := pfxlog.Logger() - log.Error("could not cast event args to event details") - return - } - - b.sendApiSessionDeletes(apiSession) -} - -func (b *Broker) sendApiSessionDeletes(apiSession *persistence.ApiSession) { - apiSessionMsg := &edge_ctrl_pb.ApiSessionRemoved{} - apiSessionMsg.Tokens = append(apiSessionMsg.Tokens, apiSession.Token) - - byteMsg, err := proto.Marshal(apiSessionMsg) - - if err != nil { - pfxlog.Logger().WithError(err).Errorf("could not marshal session removed message") - return - } - - channelMsg := channel2.NewMessage(ApiSessionRemovedType, byteMsg) - - b.sendToAllEdgeRouters(channelMsg) -} - -func (b *Broker) sessionDeleteEventHandler(args ...interface{}) { +func (broker *Broker) sessionCreated(args ...interface{}) { var session *persistence.Session if len(args) == 1 { session, _ = args[0].(*persistence.Session) @@ -431,400 +144,57 @@ func (b *Broker) sessionDeleteEventHandler(args ...interface{}) { return } - b.sendSessionDeletes(session) + broker.routerSyncStrategy.SessionAdded(session) } -func (b *Broker) sendSessionDeletes(session *persistence.Session) { - sessionsRemoved := &edge_ctrl_pb.SessionRemoved{} - sessionsRemoved.Tokens = append(sessionsRemoved.Tokens, session.Token) - - if buf, err := proto.Marshal(sessionsRemoved); err == nil { - msg := channel2.NewMessage(SessionRemovedType, buf) - // can't use sendToAllEdgeRoutersForSession b/c the session is gone - b.sendToAllEdgeRouters(msg) - } else { - pfxlog.Logger().WithError(err).Error("error sending session removed, could not marshal message content") - } -} - -func (b *Broker) sessionCreateEventHandler(args ...interface{}) { +func (broker *Broker) sessionDeleted(args ...interface{}) { var session *persistence.Session if len(args) == 1 { session, _ = args[0].(*persistence.Session) } if session == nil { - log := pfxlog.Logger() - log.Error("could not cast event args to event details") + pfxlog.Logger().Error("during broker sessionDeleted could not cast arg[0] to *persistence.Session") return } - b.sendSessionCreates(session) + broker.routerSyncStrategy.SessionDeleted(session) } -func (b *Broker) sendSessionCreates(session *persistence.Session) { - sessionAdded := &edge_ctrl_pb.SessionAdded{} - - service, err := b.ae.Handlers.EdgeService.Read(session.ServiceId) - if err != nil { - pfxlog.Logger().WithError(err).Error("could not send network session added, could not find service") - return - } - - fps, err := b.getFingerprintsByApiSessionId(session.ApiSessionId) - - if err != nil { - pfxlog.Logger().Errorf("could not obtain a fingerprint for the api session [%s] and session [%s]", session.ApiSessionId, session.Id) - return - } - - svc, err := b.modelServiceToProto(service) - - if err != nil { - pfxlog.Logger().Errorf("could not convert service [%s] to proto: %s", service.Id, err) - return - } - - sessionType := edge_ctrl_pb.SessionType_Dial - if session.Type == persistence.SessionTypeBind { - sessionType = edge_ctrl_pb.SessionType_Bind - } - - sessionAdded.Sessions = append(sessionAdded.Sessions, &edge_ctrl_pb.Session{ - Id: session.Id, - Token: session.Token, - Service: svc, - CertFingerprints: fps, - Type: sessionType, - ApiSessionId: session.ApiSessionId, - }) - - if buf, err := proto.Marshal(sessionAdded); err == nil { - msg := channel2.NewMessage(SessionAddedType, buf) - b.sendToAllEdgeRoutersForSession(session.Id, msg) - } else { - pfxlog.Logger().WithError(err).Error("error sending network session added, could not marshal message content") - } -} - -func (b *Broker) modelServiceToProto(service *model.Service) (*edge_ctrl_pb.Service, error) { - return &edge_ctrl_pb.Service{ - Name: service.Name, - Id: service.Id, - EncryptionRequired: service.EncryptionRequired, - }, nil -} - -func (b *Broker) registerEventHandlers() { - for emitter, eventNameMap := range b.events { - for en, ls := range eventNameMap { - for _, l := range ls { - emitter.AddListener(en, l) - } - } - } -} - -func (b *Broker) streamApiSessions(chunkSize int, callback func(addedMsg *edge_ctrl_pb.ApiSessionAdded)) error { - ret := &edge_ctrl_pb.ApiSessionAdded{ - IsFullState: true, - } - logger := pfxlog.Logger() - - return b.ae.GetHandlers().ApiSession.Stream("true", func(apiSession *model.ApiSession, err error) error { - if err != nil { - logger.Errorf("error reading api sessions for router: %v", err) - return nil - } - - if apiSession == nil { - //done - callback(ret) - return nil - } - - apiSessionProto, err := b.modelApiSessionToProto(apiSession.Token, apiSession.IdentityId, apiSession.Id) - - if err != nil { - logger.Errorf("error converting api session to proto: %v", err) - return nil - } - - ret.ApiSessions = append(ret.ApiSessions, apiSessionProto) - - if len(ret.ApiSessions) > chunkSize { - callback(ret) - ret = &edge_ctrl_pb.ApiSessionAdded{} - } - return nil - }) -} - -func (b *Broker) streamSessions(edgeRouterId string, chunkSize int, callback func(*edge_ctrl_pb.SessionAdded)) error { - logger := pfxlog.Logger() - - ret := &edge_ctrl_pb.SessionAdded{ - IsFullState: true, - } - - return b.ae.Handlers.Session.StreamAll(func(session *model.Session, err error) error { - if err != nil { - logger.Errorf("error reading sessions for router [%s]: %v", edgeRouterId, err) - return nil - } - - if session == nil { - //done - callback(ret) - return nil - } - - sessionProto, err := b.modelSessionToProto(session) - - if err != nil { - logger.Errorf("error converting session to proto: %v", err) - return nil - } - - ret.Sessions = append(ret.Sessions, sessionProto) - - if len(ret.Sessions) > chunkSize { - callback(ret) - ret = &edge_ctrl_pb.SessionAdded{} - } - - return nil - }) -} - -func (b *Broker) getFingerprints(identityId, apiSessionId string) ([]string, error) { - identityPrints, err := b.getIdentityAuthenticatorFingerprints(identityId) - - if err != nil { - return nil, err - } - - apiSessionPrints, err := b.getApiSessionCertificateFingerprints(apiSessionId) - - if err != nil { - return nil, err - } - - for _, apiSessionPrint := range apiSessionPrints { - identityPrints = append(identityPrints, apiSessionPrint) - } - - return identityPrints, nil -} - -func (b *Broker) getFingerprintsByApiSessionId(apiSessionId string) ([]string, error) { - apiSession, err := b.ae.GetHandlers().ApiSession.Read(apiSessionId) - - if err != nil { - return nil, fmt.Errorf("could not query fingerprints by api session id [%s]: %s", apiSessionId, err) - } - - return b.getFingerprints(apiSession.IdentityId, apiSessionId) -} - -func (b *Broker) getIdentityAuthenticatorFingerprints(identityId string) ([]string, error) { - fingerprintsMap := map[string]struct{}{} - - err := b.ae.Handlers.Identity.CollectAuthenticators(identityId, func(authenticator *model.Authenticator) error { - for _, authPrint := range authenticator.Fingerprints() { - fingerprintsMap[authPrint] = struct{}{} - } - return nil - }) - - if err != nil { - return nil, err - } - - var fingerprints []string - for fingerprint := range fingerprintsMap { - fingerprints = append(fingerprints, fingerprint) - } - - return fingerprints, nil -} - -func (b *Broker) getApiSessionCertificateFingerprints(apiSessionId string) ([]string, error) { - apiSessionCerts, err := b.ae.GetHandlers().ApiSessionCertificate.ReadByApiSessionId(apiSessionId) - - if err != nil { - return nil, err - } - - var validPrints []string - - now := time.Now() - for _, apiSessionCert := range apiSessionCerts { - if apiSessionCert.ValidAfter != nil && now.After(*apiSessionCert.ValidAfter) && - apiSessionCert.ValidBefore != nil && now.Before(*apiSessionCert.ValidBefore) { - validPrints = append(validPrints, apiSessionCert.Fingerprint) - } - } - - return validPrints, nil -} - -func (b *Broker) modelApiSessionToProto(token, identityId, apiSessionId string) (*edge_ctrl_pb.ApiSession, error) { - fingerprints, err := b.getFingerprints(identityId, apiSessionId) - if err != nil { - return nil, err - } - - return &edge_ctrl_pb.ApiSession{ - Token: token, - CertFingerprints: fingerprints, - Id: apiSessionId, - }, nil -} - -func (b *Broker) modelSessionToProto(ns *model.Session) (*edge_ctrl_pb.Session, error) { - service, err := b.ae.Handlers.EdgeService.Read(ns.ServiceId) - if err != nil { - return nil, fmt.Errorf("could not convert to session proto, could not find service: %s", err) - } - - fps, err := b.getFingerprintsByApiSessionId(ns.ApiSessionId) - - if err != nil { - return nil, fmt.Errorf("could not get fingerprints for network session: %s", err) - } - - svc, err := b.modelServiceToProto(service) - - if err != nil { - return nil, fmt.Errorf("could not convert service [%s] to proto: %s", service.Id, err) - } - - sessionType := edge_ctrl_pb.SessionType_Dial - if ns.Type == persistence.SessionTypeBind { - sessionType = edge_ctrl_pb.SessionType_Bind - } - - return &edge_ctrl_pb.Session{ - Id: ns.Id, - Token: ns.Token, - Service: svc, - CertFingerprints: fps, - Type: sessionType, - ApiSessionId: ns.ApiSessionId, - }, nil -} - -func (b *Broker) GetOnlineEdgeRouter(id string) *model.EdgeRouter { - result, found := b.edgeRouterMap.internalMap.Load(id) - if !found { - return nil - } - - entry, ok := result.(*edgeRouterEntry) - if !ok || entry.Channel.IsClosed() { - return nil - } - return entry.EdgeRouter -} - -func (b *Broker) RouterConnected(r *network.Router) { - go func() { - if r.Fingerprint != nil { - if edgeRouter, _ := b.ae.Handlers.EdgeRouter.ReadOneByFingerprint(*r.Fingerprint); edgeRouter != nil { - b.sendHello(r) - } - } - }() -} - -func (b *Broker) sendHello(r *network.Router) { - serverVersion := build.GetBuildInfo().Version() - serverHello := &edge_ctrl_pb.ServerHello{ - Version: serverVersion, - } - - buf, err := proto.Marshal(serverHello) - if err != nil { - pfxlog.Logger().WithError(err).Error("could not marshal serverHello") - return - } - - if err = r.Control.SendWithTimeout(channel2.NewMessage(ServerHelloType, buf), 10*time.Second); err != nil { - pfxlog.Logger().WithError(err).Error("timed out sending serverHello message for edge router") - return - } -} - -func (b *Broker) ReceiveHello(r *network.Router, edgeRouter *model.EdgeRouter, respHello *edge_ctrl_pb.ClientHello) { - serverVersion := build.GetBuildInfo().Version() - - entry := pfxlog.Logger(). - WithField("hostname", respHello.Hostname). - WithField("protocols", respHello.Protocols). - WithField("protocolPorts", respHello.ProtocolPorts). - WithField("data", respHello.Data) - - if r.VersionInfo != nil { - entry.WithField("version", r.VersionInfo.Version). - WithField("revision", r.VersionInfo.Revision). - WithField("buildDate", r.VersionInfo.BuildDate). - WithField("os", r.VersionInfo.OS). - WithField("arch", r.VersionInfo.Arch) - } - - entry.Info("edge router responded with client hello") - - protocols := map[string]string{} - for _, p := range respHello.ProtocolPorts { - parts := strings.Split(p, ":") - ingressUrl := fmt.Sprintf("%s://%s:%s", parts[0], respHello.Hostname, parts[1]) - protocols[parts[0]] = ingressUrl - } - - edgeRouter.Hostname = &respHello.Hostname - edgeRouter.EdgeRouterProtocols = protocols - edgeRouter.VersionInfo = r.VersionInfo - - //todo: restrict version? - pfxlog.Logger().Infof("edge router connecting with version [%s] to controller with version [%s]", respHello.Version, serverVersion) - - b.AddEdgeRouter(r.Control, edgeRouter) -} - -func (b *Broker) RouterDisconnected(r *network.Router) { - go func() { - //ensure this wasn't the same router being started multiple times and the 2nd connection being refused w/ a close - if r.Fingerprint != nil && !b.ae.HostController.GetNetwork().ConnectedRouter(r.Id) { - if edgeRouter, _ := b.ae.Handlers.EdgeRouter.ReadOneByFingerprint(*r.Fingerprint); edgeRouter != nil { - b.edgeRouterMap.RemoveEntry(edgeRouter.Id) - } - } - }() -} - -func (b *Broker) apiSessionCertificateEventHandler(args ...interface{}) { +func (broker *Broker) apiSessionCertificateHandler(args ...interface{}) { var apiSessionCert *persistence.ApiSessionCertificate if len(args) == 1 { apiSessionCert, _ = args[0].(*persistence.ApiSessionCertificate) } if apiSessionCert == nil { - log := pfxlog.Logger() - log.Error("could not cast event args to event details: create/delete api session cert") + pfxlog.Logger().Error("during broker apiSessionCertificateEvent could not cast arg[0] to *persistence.ApiSessionCertificate") return } var apiSession *persistence.ApiSession var err error - err = b.ae.GetDbProvider().GetDb().View(func(tx *bbolt.Tx) error { - apiSession, err = b.ae.GetStores().ApiSession.LoadOneById(tx, apiSessionCert.ApiSessionId) + err = broker.ae.GetDbProvider().GetDb().View(func(tx *bbolt.Tx) error { + apiSession, err = broker.ae.GetStores().ApiSession.LoadOneById(tx, apiSessionCert.ApiSessionId) return err }) if err != nil { - pfxlog.Logger().WithError(err).Error("could not process API Session certificate creation. Failed to query for parent API Session") + pfxlog.Logger().WithError(err).Error("could not process API Session certificate event, failed to query for parent API Session") return } - b.sendApiSessionUpdates(apiSession) + broker.routerSyncStrategy.ApiSessionUpdated(apiSession, apiSessionCert) +} + +func (broker *Broker) IsEdgeRouterOnline(id string) bool { + er, _ := broker.GetOnlineEdgeRouter(id) + return er != nil +} + +func (broker *Broker) GetOnlineEdgeRouter(id string) (*model.EdgeRouter, RouterSyncStatus) { + return broker.routerSyncStrategy.GetOnlineEdgeRouter(id) +} + +func (broker *Broker) Stop() { + broker.routerSyncStrategy.Stop() } diff --git a/controller/env/sync.go b/controller/env/sync.go new file mode 100644 index 000000000..e39264d24 --- /dev/null +++ b/controller/env/sync.go @@ -0,0 +1,78 @@ +/* + 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 env + +import ( + "github.com/openziti/edge/controller/model" + "github.com/openziti/edge/controller/persistence" + "github.com/openziti/fabric/controller/network" +) + +// Aliased type for router strategies +type RouterSyncStrategyType string + +// Aliased type for router sync status +type RouterSyncStatus string + +const ( + RouterSyncNew RouterSyncStatus = "SYNC_NEW" //connection accepted but no strategy actions have been taken + RouterSyncQueued RouterSyncStatus = "SYNC_QUEUED" //connection handed to strategy, but not processed + RouterSyncHello RouterSyncStatus = "SYNC_HELLO" //connection is beginning hello cycle + RouterSyncHelloWait RouterSyncStatus = "SYNC_HELLO_WAIT" //hello received from router, but there are too many synchronizing routers + RouterSyncResyncWait RouterSyncStatus = "SYNC_RESYNC_WAIT" //router requested a resync, in queue + RouterSynInProgress RouterSyncStatus = "SYNC_IN_PROGRESS" //hello finished, starting to send state + RouterSyncDone RouterSyncStatus = "SYNC_DONE" //initial state sent + + //Error states + RouterSyncUnknown RouterSyncStatus = "SYNC_UNKNOWN" //the router is currently unknown + RouterSyncDisconnected RouterSyncStatus = "SYNC_DISCONNECTED" //strategy was disconnected before finishing + RouterSyncHelloTimeout RouterSyncStatus = "SYNC_HELLO_TIMEOUT" //sync failed due to a hello timeout. + + //msg headers + SyncStrategyTypeHeader = 1013 + SyncStrategyStateHeader = 1014 +) + +// RouterSyncStrategy handles the life cycle of an Edge Router connecting to the controller, synchronizing +// any upfront state and then maintaining state after that. +type RouterSyncStrategy interface { + Type() RouterSyncStrategyType + Status(id string) RouterSyncStatus + GetOnlineEdgeRouter(id string) (*model.EdgeRouter, RouterSyncStatus) + Stop() + RouterConnectionHandler + RouterSynchronizerEventHandler +} + +// RouterConnectionHandler is responsible for handling router connect/disconnect for synchronizing state. +// This is intended for API Session but additional state is possible. Implementations may bind additional +// handlers to the channel. +type RouterConnectionHandler interface { + RouterConnected(edgeRouter *model.EdgeRouter, router *network.Router) + RouterDisconnected(router *network.Router) +} + +// RouterSynchronizerEventHandler is responsible for keeping Edge Routers up to date on API Sessions +type RouterSynchronizerEventHandler interface { + ApiSessionAdded(apiSession *persistence.ApiSession) + ApiSessionUpdated(apiSession *persistence.ApiSession, apiSessionCert *persistence.ApiSessionCertificate) + ApiSessionDeleted(apiSession *persistence.ApiSession) + + //todo: To be removed inline session creation + SessionAdded(session *persistence.Session) + SessionDeleted(session *persistence.Session) +} diff --git a/controller/handler_edge_ctrl/hello.go b/controller/handler_edge_ctrl/hello.go index 631196bfc..79d4580e1 100644 --- a/controller/handler_edge_ctrl/hello.go +++ b/controller/handler_edge_ctrl/hello.go @@ -21,16 +21,19 @@ import ( "github.com/michaelquigley/pfxlog" "github.com/openziti/edge/controller/env" "github.com/openziti/edge/pb/edge_ctrl_pb" + "github.com/openziti/fabric/controller/network" "github.com/openziti/foundation/channel2" ) type helloHandler struct { - appEnv *env.AppEnv + appEnv *env.AppEnv + callback func(r *network.Router, respHello *edge_ctrl_pb.ClientHello) } -func NewHelloHandler(appEnv *env.AppEnv) *helloHandler { +func NewHelloHandler(appEnv *env.AppEnv, callback func(r *network.Router, respHello *edge_ctrl_pb.ClientHello)) *helloHandler { return &helloHandler{ - appEnv: appEnv, + appEnv: appEnv, + callback: callback, } } @@ -52,17 +55,5 @@ func (h *helloHandler) HandleReceive(msg *channel2.Message, ch channel2.Channel) return } - if r.Fingerprint == nil { - pfxlog.Logger().Errorf("router %v is not enrolled, closing channel", ch.Id().Token) - _ = ch.Close() - return - } - - edgeRouter, _ := h.appEnv.Handlers.EdgeRouter.ReadOneByFingerprint(*r.Fingerprint) - if edgeRouter == nil { - pfxlog.Logger().Errorf("edge hello received for non-edge router %v", ch.Id().Token) - return - } - - h.appEnv.Broker.ReceiveHello(r, edgeRouter, respHello) + h.callback(r, respHello) } diff --git a/controller/handler_edge_ctrl/resync.go b/controller/handler_edge_ctrl/resync.go new file mode 100644 index 000000000..8c200f5da --- /dev/null +++ b/controller/handler_edge_ctrl/resync.go @@ -0,0 +1,59 @@ +/* + 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 handler_edge_ctrl + +import ( + "github.com/golang/protobuf/proto" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/edge/controller/env" + "github.com/openziti/edge/pb/edge_ctrl_pb" + "github.com/openziti/fabric/controller/network" + "github.com/openziti/foundation/channel2" +) + +type resyncHandler struct { + appEnv *env.AppEnv + callback func(r *network.Router, respHello *edge_ctrl_pb.RequestClientReSync) +} + +func NewResyncHandler(appEnv *env.AppEnv, callback func(r *network.Router, respHello *edge_ctrl_pb.RequestClientReSync)) *resyncHandler { + return &resyncHandler{ + appEnv: appEnv, + callback: callback, + } +} + +func (h *resyncHandler) ContentType() int32 { + return env.RequestClientReSyncType +} + +func (h *resyncHandler) HandleReceive(msg *channel2.Message, ch channel2.Channel) { + resyncReq := &edge_ctrl_pb.RequestClientReSync{} + if err := proto.Unmarshal(msg.Body, resyncReq); err != nil { + pfxlog.Logger().WithError(err).Error("could not unmarshal RequestClientReSync") + return + } + + r, err := h.appEnv.GetHostController().GetNetwork().GetRouter(ch.Id().Token) + if err != nil { + pfxlog.Logger().WithError(err).Errorf("could not find router %v, closing channel", ch.Id().Token) + _ = ch.Close() + return + } + + h.callback(r, resyncReq) +} diff --git a/controller/internal/routes/current_identity_api_model.go b/controller/internal/routes/current_identity_api_model.go index b0f307340..83b4546f9 100644 --- a/controller/internal/routes/current_identity_api_model.go +++ b/controller/internal/routes/current_identity_api_model.go @@ -163,7 +163,7 @@ func MapCurrentIdentityEdgeRouterToRestEntity(ae *env.AppEnv, _ *response.Reques func MapCurrentIdentityEdgeRouterToRestModel(ae *env.AppEnv, router *model.EdgeRouter) (*rest_model.CurrentIdentityEdgeRouterDetail, error) { hostname := "" protocols := map[string]string{} - onlineEdgeRouter := ae.Broker.GetOnlineEdgeRouter(router.Id) + onlineEdgeRouter, _ := ae.Broker.GetOnlineEdgeRouter(router.Id) isOnline := onlineEdgeRouter != nil diff --git a/controller/internal/routes/edge_router_api_model.go b/controller/internal/routes/edge_router_api_model.go index b7b84bfe3..591089b53 100644 --- a/controller/internal/routes/edge_router_api_model.go +++ b/controller/internal/routes/edge_router_api_model.go @@ -119,7 +119,8 @@ func MapEdgeRouterToRestModel(ae *env.AppEnv, router *model.EdgeRouter) (*rest_m revision := "" version := "" - onlineEdgeRouter := ae.Broker.GetOnlineEdgeRouter(router.Id) + onlineEdgeRouter, syncStatus := ae.Broker.GetOnlineEdgeRouter(router.Id) + syncStatusStr := string(syncStatus) isOnline := onlineEdgeRouter != nil @@ -134,6 +135,7 @@ func MapEdgeRouterToRestModel(ae *env.AppEnv, router *model.EdgeRouter) (*rest_m revision = onlineEdgeRouter.VersionInfo.Revision version = onlineEdgeRouter.VersionInfo.Version } + } ret := &rest_model.EdgeRouterDetail{ @@ -149,6 +151,7 @@ func MapEdgeRouterToRestModel(ae *env.AppEnv, router *model.EdgeRouter) (*rest_m Fingerprint: stringz.OrEmpty(router.Fingerprint), Hostname: &hostname, SupportedProtocols: protocols, + SyncStatus: &syncStatusStr, VersionInfo: &rest_model.VersionInfo{ Os: &os, Arch: &arch, diff --git a/controller/internal/routes/session_api_model.go b/controller/internal/routes/session_api_model.go index e84879048..5103ee032 100644 --- a/controller/internal/routes/session_api_model.go +++ b/controller/internal/routes/session_api_model.go @@ -122,7 +122,7 @@ func getSessionEdgeRouters(ae *env.AppEnv, ns *model.Session) ([]*rest_model.Ses } for _, edgeRouter := range edgeRoutersForSession.EdgeRouters { - onlineEdgeRouter := ae.Broker.GetOnlineEdgeRouter(edgeRouter.Id) + onlineEdgeRouter, _ := ae.Broker.GetOnlineEdgeRouter(edgeRouter.Id) if onlineEdgeRouter != nil { restModel := &rest_model.SessionEdgeRouter{ diff --git a/controller/model/api_session_handlers.go b/controller/model/api_session_handlers.go index 39d21f2cf..6337d4021 100644 --- a/controller/model/api_session_handlers.go +++ b/controller/model/api_session_handlers.go @@ -18,6 +18,7 @@ package model import ( "fmt" + "github.com/lucsky/cuid" "github.com/openziti/edge/controller/persistence" "github.com/openziti/fabric/controller/models" "github.com/openziti/foundation/storage/ast" @@ -43,6 +44,7 @@ func (handler *ApiSessionHandler) newModelEntity() boltEntitySink { } func (handler *ApiSessionHandler) Create(entity *ApiSession) (string, error) { + entity.Id = cuid.New() //use cuids which are longer than shortids but are monotonic return handler.createEntity(entity) } diff --git a/controller/model/session_handlers.go b/controller/model/session_handlers.go index 4f655a601..f39f69dec 100644 --- a/controller/model/session_handlers.go +++ b/controller/model/session_handlers.go @@ -18,6 +18,7 @@ package model import ( "fmt" + "github.com/lucsky/cuid" "github.com/openziti/fabric/controller/models" "github.com/openziti/foundation/storage/ast" "github.com/openziti/foundation/storage/boltz" @@ -41,6 +42,7 @@ func (handler *SessionHandler) newModelEntity() boltEntitySink { } func (handler *SessionHandler) Create(entity *Session) (string, error) { + entity.Id = cuid.New() //use cuids which are longer than shortids but are monotonic return handler.createEntity(entity) } diff --git a/controller/server/controller.go b/controller/server/controller.go index aca41fb16..4982accce 100644 --- a/controller/server/controller.go +++ b/controller/server/controller.go @@ -23,6 +23,7 @@ import ( "github.com/openziti/edge/controller" "github.com/openziti/edge/controller/apierror" "github.com/openziti/edge/controller/response" + sync2 "github.com/openziti/edge/controller/sync_strats" "github.com/openziti/edge/controller/timeout" "github.com/openziti/edge/rest_server" "github.com/openziti/fabric/controller/xtv" @@ -129,7 +130,6 @@ func (c *Controller) SetHostController(h env.HostController) { func (c *Controller) GetCtrlHandlers() []channel2.ReceiveHandler { return []channel2.ReceiveHandler{ handler_edge_ctrl.NewSessionHeartbeatHandler(c.AppEnv), - handler_edge_ctrl.NewHelloHandler(c.AppEnv), } } @@ -188,7 +188,15 @@ func (c *Controller) Initialize() { } //after InitPersistence - c.AppEnv.Broker = env.NewBroker(c.AppEnv) + c.AppEnv.Broker = env.NewBroker(c.AppEnv, sync2.NewInstantStrategy(c.AppEnv, sync2.InstantStrategyOptions{ + MaxQueuedRouterConnects: 100, + MaxQueuedClientHellos: 100, + RouterConnectWorkerCount: 10, + SyncWorkerCount: 10, + RouterTxBufferSize: 100, + HelloSendTimeout: 10 * time.Second, + SessionChunkSize: 100, + })) servicePolicyEnforcer := policy.NewServicePolicyEnforcer(c.AppEnv, policyAppWanFreq) if err := c.policyEngine.AddOperation(servicePolicyEnforcer); err != nil { @@ -357,6 +365,8 @@ func (c *Controller) Shutdown() { c.apiServer.Shutdown(ctx) _ = c.policyEngine.Stop() + c.AppEnv.Broker.Stop() + pfxlog.Logger().Info("edge controller shutting down") } diff --git a/controller/sync_strats/marshal.go b/controller/sync_strats/marshal.go new file mode 100644 index 000000000..4aa35c114 --- /dev/null +++ b/controller/sync_strats/marshal.go @@ -0,0 +1,144 @@ +/* + 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 sync_strats + +import ( + "fmt" + "github.com/openziti/edge/controller/env" + "github.com/openziti/edge/controller/model" + "github.com/openziti/edge/controller/persistence" + "github.com/openziti/edge/pb/edge_ctrl_pb" + "time" +) + +func apiSessionToProto(ae *env.AppEnv, token, identityId, apiSessionId string) (*edge_ctrl_pb.ApiSession, error) { + fingerprints, err := getFingerprints(ae, identityId, apiSessionId) + if err != nil { + return nil, err + } + + return &edge_ctrl_pb.ApiSession{ + Token: token, + CertFingerprints: fingerprints, + Id: apiSessionId, + }, nil +} + +func sessionToProto(ae *env.AppEnv, session *persistence.Session) (*edge_ctrl_pb.Session, error) { + service, err := ae.Handlers.EdgeService.Read(session.ServiceId) + if err != nil { + return nil, fmt.Errorf("could not convert to session proto, could not find service: %s", err) + } + + fps, err := getFingerprintsByApiSessionId(ae, session.ApiSessionId) + + if err != nil { + return nil, fmt.Errorf("could not get fingerprints for network session: %s", err) + } + + serviceProto := &edge_ctrl_pb.Service{ + Name: service.Name, + Id: service.Id, + EncryptionRequired: service.EncryptionRequired, + } + + sessionType := edge_ctrl_pb.SessionType_Dial + if session.Type == persistence.SessionTypeBind { + sessionType = edge_ctrl_pb.SessionType_Bind + } + + return &edge_ctrl_pb.Session{ + Id: session.Id, + Token: session.Token, + Service: serviceProto, + CertFingerprints: fps, + Type: sessionType, + ApiSessionId: session.ApiSessionId, + }, nil +} + +func getFingerprintsByApiSessionId(ae *env.AppEnv, apiSessionId string) ([]string, error) { + apiSession, err := ae.GetHandlers().ApiSession.Read(apiSessionId) + + if err != nil { + return nil, fmt.Errorf("could not query fingerprints by api session id [%s]: %s", apiSessionId, err) + } + + return getFingerprints(ae, apiSession.IdentityId, apiSessionId) +} + +func getFingerprints(ae *env.AppEnv, identityId, apiSessionId string) ([]string, error) { + identityPrints, err := getIdentityAuthenticatorFingerprints(ae, identityId) + + if err != nil { + return nil, err + } + + apiSessionPrints, err := getApiSessionCertificateFingerprints(ae, apiSessionId) + + if err != nil { + return nil, err + } + + for _, apiSessionPrint := range apiSessionPrints { + identityPrints = append(identityPrints, apiSessionPrint) + } + + return identityPrints, nil +} + +func getIdentityAuthenticatorFingerprints(ae *env.AppEnv, identityId string) ([]string, error) { + fingerprintsMap := map[string]struct{}{} + + err := ae.Handlers.Identity.CollectAuthenticators(identityId, func(authenticator *model.Authenticator) error { + for _, authPrint := range authenticator.Fingerprints() { + fingerprintsMap[authPrint] = struct{}{} + } + return nil + }) + + if err != nil { + return nil, err + } + + var fingerprints []string + for fingerprint := range fingerprintsMap { + fingerprints = append(fingerprints, fingerprint) + } + + return fingerprints, nil +} + +func getApiSessionCertificateFingerprints(ae *env.AppEnv, apiSessionId string) ([]string, error) { + apiSessionCerts, err := ae.GetHandlers().ApiSessionCertificate.ReadByApiSessionId(apiSessionId) + + if err != nil { + return nil, err + } + + var validPrints []string + + now := time.Now() + for _, apiSessionCert := range apiSessionCerts { + if apiSessionCert.ValidAfter != nil && now.After(*apiSessionCert.ValidAfter) && + apiSessionCert.ValidBefore != nil && now.Before(*apiSessionCert.ValidBefore) { + validPrints = append(validPrints, apiSessionCert.Fingerprint) + } + } + + return validPrints, nil +} diff --git a/controller/sync_strats/rtx.go b/controller/sync_strats/rtx.go new file mode 100644 index 000000000..abeb8fa26 --- /dev/null +++ b/controller/sync_strats/rtx.go @@ -0,0 +1,156 @@ +/* + 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 sync_strats + +import ( + "github.com/michaelquigley/pfxlog" + "github.com/openziti/edge/controller/env" + "github.com/openziti/edge/controller/model" + "github.com/openziti/edge/eid" + "github.com/openziti/fabric/controller/network" + "github.com/openziti/foundation/channel2" + "github.com/openziti/foundation/util/concurrenz" + "github.com/sirupsen/logrus" + "sync" +) + +// RouterSender represents a connection from an Edge Router to the controller. Used +// to asynchronously buffer and send messages to an Edge Router via Start() then Send() +type RouterSender struct { + Id string + EdgeRouter *model.EdgeRouter + Router *network.Router + Status env.RouterSyncStatus + send chan *channel2.Message + stop chan interface{} + running concurrenz.AtomicBoolean + stopping concurrenz.AtomicBoolean +} + +func newRouterSender(edgeRouter *model.EdgeRouter, router *network.Router, sendBufferSize int) *RouterSender { + return &RouterSender{ + Id: eid.New(), + EdgeRouter: edgeRouter, + Router: router, + Status: env.RouterSyncNew, + send: make(chan *channel2.Message, sendBufferSize), + stop: make(chan interface{}, 0), + running: concurrenz.AtomicBoolean(0), + stopping: concurrenz.AtomicBoolean(0), + } +} + +func (rtx *RouterSender) Start() { + if rtx.running.CompareAndSwap(false, true) { + go rtx.run() + } +} + +func (rtx *RouterSender) Stop() { + if rtx.stopping.CompareAndSwap(false, true) { + go func() { + rtx.stop <- struct{}{} + }() + } +} + +func (rtx *RouterSender) run() { + for { + select { + case <-rtx.stop: + rtx.running.Set(false) + rtx.stopping.Set(false) + return + case msg := <-rtx.send: + if !rtx.Router.Control.IsClosed() { + _ = rtx.Router.Control.Send(msg) + } + } + } +} + +func (rtx *RouterSender) logger() *logrus.Entry { + return pfxlog.Logger(). + WithField("routerTxId", rtx.Id). + WithField("routerId", rtx.Router.Id). + WithField("routerName", rtx.Router.Name). + WithField("routerFingerprint", rtx.Router.Fingerprint). + WithField("routerChannelIsOpen", !rtx.Router.Control.IsClosed()) +} + +func (rtx *RouterSender) Send(msg *channel2.Message) { + rtx.send <- msg +} + +// Map used make working with internal RouterSender easier as sync.Map accepts and returns interface{} +type routerTxMap struct { + internalMap *sync.Map //id -> RouterSender +} + +func (m *routerTxMap) Add(id string, routerMessageTxer *RouterSender) { + m.internalMap.Store(id, routerMessageTxer) + routerMessageTxer.Start() +} + +func (m *routerTxMap) Get(id string) *RouterSender { + val, found := m.internalMap.Load(id) + if !found { + return nil + } + return val.(*RouterSender) +} + +func (m *routerTxMap) Remove(id string) { + entry := m.Get(id) + if entry != nil { + entry.Stop() + m.internalMap.Delete(id) + } +} + +func (m *routerTxMap) Range(f func(entries *RouterSender) bool) { + m.internalMap.Range(func(edgeRouterId, value interface{}) bool { + if rtx, ok := value.(*RouterSender); ok { + return f(rtx) + } + pfxlog.Logger().Panic("could not convert edge router entry") + return false + }) +} + +// Helper to generate channel2.ReceiveHandler instances from a contentType and function +func newReceiveHandlerFunc(contentType int32, handler func(m *channel2.Message, ch channel2.Channel)) channel2.ReceiveHandler { + return receiveHandlerFunc{ + contentType: contentType, + handler: handler, + } +} + +var _ channel2.ReceiveHandler = &receiveHandlerFunc{} + +type receiveHandlerFunc struct { + contentType int32 + handler func(m *channel2.Message, ch channel2.Channel) +} + +func (r receiveHandlerFunc) ContentType() int32 { + return r.contentType +} + +func (r receiveHandlerFunc) HandleReceive(m *channel2.Message, ch channel2.Channel) { + r.handler(m, ch) +} diff --git a/controller/sync_strats/sync_instant.go b/controller/sync_strats/sync_instant.go new file mode 100644 index 000000000..4236661dc --- /dev/null +++ b/controller/sync_strats/sync_instant.go @@ -0,0 +1,562 @@ +/* + 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 sync_strats + +import ( + "encoding/json" + "fmt" + "github.com/golang/protobuf/proto" + "github.com/lucsky/cuid" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/edge/build" + "github.com/openziti/edge/controller/env" + "github.com/openziti/edge/controller/handler_edge_ctrl" + "github.com/openziti/edge/controller/model" + "github.com/openziti/edge/controller/persistence" + "github.com/openziti/edge/pb/edge_ctrl_pb" + "github.com/openziti/fabric/controller/network" + "github.com/openziti/foundation/channel2" + "github.com/openziti/foundation/storage/ast" + "go.etcd.io/bbolt" + "strings" + "sync" + "time" +) + +const ( + RouterSyncStrategyInstant env.RouterSyncStrategyType = "instant" +) + +var _ env.RouterSyncStrategy = &InstantStrategy{} + +// Options for the instant strategy. +// - MaxQueuedRouterConnects - max number of router connected events to buffer +// - MaxQueuedClientHellos - max number of client hello messages to buffer +// - RouterConnectWorkerCount - max number of workers used to process router connections +// - SyncWorkerCount - max number of workers used to send api sessions/session data +// - RouterTxBufferSize - max number of messages buffered to be send to a router +// - HelloSendTimeout - the max amount of time per worker to wait to send hellos +// - SessionChunkSize - the number of sessions to send in each message +type InstantStrategyOptions struct { + MaxQueuedRouterConnects int32 + MaxQueuedClientHellos int32 + RouterConnectWorkerCount int32 + SyncWorkerCount int32 + RouterTxBufferSize int + HelloSendTimeout time.Duration + SessionChunkSize int +} + +// Original API Session synchronization implementation. Assumes that on connect, the router requires and instant +// and full set of API Sessions. Send individual create, update, delete events for sessions after synchronization. +// +// This strategy uses a series of queus and workers to managed sychronization state. The order of events is as follows: +// 1. An edge router connects to the controller, triggering RouterConnected() +// 2. A RouterSender is created encapsulating the Edge Router, Router, and Sync State +// 3. The RouterSender is queued on the routerConnectedQueue channel which buffers up to options.MaxQueuedRouterConnects +// 4. The routerConnectedQueue is read and the edge server hello is sent +// 5. The controller waits for a client hello to be recieved via ReceiveClientHello message +// 6. The client hello is used to identity the RouterSender associated with the client and is queued on +// the receivedClientHelloQueue channel which buffers up to options.MaxQueuedClientHellos +// 7. A startSynchronizeWorker will pick up the RouterSender from the receivedClientHelloQueue and being to +// send data to the edge router via the RouterSender +type InstantStrategy struct { + InstantStrategyOptions + + rtxMap *routerTxMap + + helloHandler channel2.ReceiveHandler + resyncHandler channel2.ReceiveHandler + ae *env.AppEnv + + routerConnectedQueue chan *RouterSender + receivedClientHelloQueue chan *RouterSender + + stop chan struct{} +} + +func NewInstantStrategy(ae *env.AppEnv, options InstantStrategyOptions) *InstantStrategy { + if options.MaxQueuedRouterConnects <= 0 { + pfxlog.Logger().Panicf("MaxQueuedRouterConnects for InstantStrategy cannot be less than 1, got %d", options.MaxQueuedRouterConnects) + } + + if options.MaxQueuedClientHellos <= 0 { + pfxlog.Logger().Panicf("MaxQueuedClientHellos for InstantStrategy cannot be less than 1, got %d", options.MaxQueuedClientHellos) + } + + if options.RouterConnectWorkerCount <= 0 { + pfxlog.Logger().Panicf("RouterConnectWorkerCount for InstantStrategy cannot be less than 1, got %d", options.RouterConnectWorkerCount) + } + + if options.SyncWorkerCount <= 0 { + pfxlog.Logger().Panicf("SyncWorkerCount for InstantStrategy cannot be less than 1, got %d", options.SyncWorkerCount) + } + + if options.RouterTxBufferSize < 0 { + pfxlog.Logger().Panicf("RouterTxBufferSize for InstantStrategy cannot be less than 0, got %d", options.MaxQueuedRouterConnects) + } + + if options.SessionChunkSize <= 0 { + pfxlog.Logger().Panicf("SessionChunkSize for InstantStrategy cannot be less than 1, got %d", options.SessionChunkSize) + } + + strategy := &InstantStrategy{ + InstantStrategyOptions: options, + rtxMap: &routerTxMap{ + internalMap: &sync.Map{}, + }, + ae: ae, + routerConnectedQueue: make(chan *RouterSender, options.MaxQueuedRouterConnects), + receivedClientHelloQueue: make(chan *RouterSender, options.MaxQueuedClientHellos), + + stop: make(chan struct{}, 0), + } + + strategy.helloHandler = handler_edge_ctrl.NewHelloHandler(ae, strategy.ReceiveClientHello) + strategy.resyncHandler = handler_edge_ctrl.NewResyncHandler(ae, strategy.ReceiveResync) + + for i := int32(0); i < options.RouterConnectWorkerCount; i++ { + go strategy.startHandleRouterConnectWorker() + } + + for i := int32(0); i < options.SyncWorkerCount; i++ { + go strategy.startSynchronizeWorker() + } + + return strategy +} +func (strategy *InstantStrategy) GetOnlineEdgeRouter(id string) (*model.EdgeRouter, env.RouterSyncStatus) { + rtx := strategy.rtxMap.Get(id) + + if rtx != nil { + return rtx.EdgeRouter, rtx.Status + } + + return nil, env.RouterSyncUnknown +} + +func (strategy *InstantStrategy) Status(id string) env.RouterSyncStatus { + rtx := strategy.rtxMap.Get(id) + if rtx == nil { + return env.RouterSyncUnknown + } + + return rtx.Status +} + +func (strategy *InstantStrategy) Type() env.RouterSyncStrategyType { + return RouterSyncStrategyInstant +} + +func (strategy *InstantStrategy) Stop() { + if strategy.stop != nil { + close(strategy.stop) + strategy.stop = nil + } +} + +func (strategy *InstantStrategy) RouterConnected(edgeRouter *model.EdgeRouter, router *network.Router) { + rtx := newRouterSender(edgeRouter, router, strategy.RouterTxBufferSize) + rtx.Status = env.RouterSyncQueued + + log := pfxlog.Logger().WithField("sync_strategy", strategy.Type()). + WithField("syncStatus", rtx.Status). + WithField("routerId", rtx.Router.Id). + WithField("routerName", rtx.Router.Name). + WithField("routerFingerprint", rtx.Router.Fingerprint) + + log.Info("edge router connected, adding to sync routerConnectedQueue") + + strategy.rtxMap.Add(router.Id, rtx) + + strategy.routerConnectedQueue <- rtx +} + +func (strategy *InstantStrategy) RouterDisconnected(router *network.Router) { + strategy.rtxMap.Remove(router.Id) +} + +func (strategy *InstantStrategy) ApiSessionAdded(apiSession *persistence.ApiSession) { + logger := pfxlog.Logger().WithField("strategy", strategy.Type()) + + apiSessionProto, err := apiSessionToProto(strategy.ae, apiSession.Token, apiSession.IdentityId, apiSession.Id) + + if err != nil { + logger.WithField("apiSessionId", apiSession.Id). + Errorf("error for individual api session added, could not convert to proto: %v", err) + return + } + + state := &InstantSyncState{ + Id: cuid.New(), + IsLast: true, + Sequence: 0, + } + + strategy.rtxMap.Range(func(rtx *RouterSender) bool { + strategy.sendApiSessionAdded(rtx, false, state, []*edge_ctrl_pb.ApiSession{apiSessionProto}) + return true + }) +} + +func (strategy *InstantStrategy) ApiSessionUpdated(apiSession *persistence.ApiSession, _ *persistence.ApiSessionCertificate) { + logger := pfxlog.Logger().WithField("strategy", strategy.Type()) + + apiSessionProto, err := apiSessionToProto(strategy.ae, apiSession.Token, apiSession.IdentityId, apiSession.Id) + + if err != nil { + logger.WithField("apiSessionId", apiSession.Id). + Errorf("error for individual api session added, could not convert to proto: %v", err) + return + } + + apiSessionAdded := &edge_ctrl_pb.ApiSessionAdded{ + IsFullState: false, + ApiSessions: []*edge_ctrl_pb.ApiSession{apiSessionProto}, + } + + strategy.rtxMap.Range(func(rtx *RouterSender) bool { + content, _ := proto.Marshal(apiSessionAdded) + msg := channel2.NewMessage(env.ApiSessionUpdatedType, content) + msg.Headers[env.SyncStrategyTypeHeader] = []byte(strategy.Type()) + msg.Headers[env.SyncStrategyStateHeader] = nil + rtx.Send(msg) + return true + }) +} + +func (strategy *InstantStrategy) ApiSessionDeleted(apiSession *persistence.ApiSession) { + sessionRemoved := &edge_ctrl_pb.ApiSessionRemoved{ + Tokens: []string{apiSession.Token}, + } + + strategy.rtxMap.Range(func(rtx *RouterSender) bool { + content, _ := proto.Marshal(sessionRemoved) + msg := channel2.NewMessage(env.ApiSessionRemovedType, content) + rtx.Send(msg) + return true + }) +} + +func (strategy *InstantStrategy) SessionAdded(session *persistence.Session) { + logger := pfxlog.Logger().WithField("strategy", strategy.Type()) + + sessionProto, err := sessionToProto(strategy.ae, session) + + if err != nil { + logger.WithField("sessionId", session.Id). + Errorf("error for individual session added, could not convert to proto: %v", err) + return + } + + state := &InstantSyncState{ + Id: cuid.New(), + IsLast: true, + Sequence: 0, + } + strategy.rtxMap.Range(func(rtx *RouterSender) bool { + strategy.sendSessionAdded(rtx, false, state, []*edge_ctrl_pb.Session{sessionProto}) + return true + }) +} + +func (strategy *InstantStrategy) SessionDeleted(session *persistence.Session) { + sessionRemoved := &edge_ctrl_pb.SessionRemoved{ + Tokens: []string{session.Token}, + } + + strategy.rtxMap.Range(func(rtx *RouterSender) bool { + content, _ := proto.Marshal(sessionRemoved) + msg := channel2.NewMessage(env.SessionRemovedType, content) + rtx.Send(msg) + return true + }) +} + +func (strategy *InstantStrategy) startHandleRouterConnectWorker() { + select { + case <-strategy.stop: + return + case rtx := <-strategy.routerConnectedQueue: + strategy.hello(rtx) + } +} + +func (strategy *InstantStrategy) startSynchronizeWorker() { + select { + case <-strategy.stop: + return + case rtx := <-strategy.receivedClientHelloQueue: + strategy.synchronize(rtx) + } +} + +func (strategy *InstantStrategy) hello(rtx *RouterSender) { + logger := rtx.logger().WithField("strategy", strategy.Type()) + + logger.Info("edge router sync starting") + + if rtx.Router.Control.IsClosed() { + rtx.Status = env.RouterSyncDisconnected + logger.WithField("syncStatus", rtx.Status).Info("edge router sync aborting, edge router disconnected before sync started") + return + } + + rtx.Router.Control.AddReceiveHandler(strategy.helloHandler) + rtx.Status = env.RouterSyncHello + logger.WithField("syncStatus", rtx.Status).Info("sending edge router hello") + strategy.sendHello(rtx) +} + +func (strategy *InstantStrategy) sendHello(rtx *RouterSender) { + logger := rtx.logger().WithField("strategy", strategy.Type()) + serverVersion := build.GetBuildInfo().Version() + serverHello := &edge_ctrl_pb.ServerHello{ + Version: serverVersion, + } + + buf, err := proto.Marshal(serverHello) + if err != nil { + logger.WithError(err).Error("could not marshal serverHello") + return + } + + if err = rtx.Router.Control.SendWithTimeout(channel2.NewMessage(env.ServerHelloType, buf), strategy.HelloSendTimeout); err != nil { + if rtx.Router.Control.IsClosed() { + rtx.Status = env.RouterSyncDisconnected + rtx.logger().WithError(err).Error("timed out sending serverHello message for edge router, connection closed, giving up") + } else { + rtx.Status = env.RouterSyncHelloTimeout + rtx.logger().WithError(err).Error("timed out sending serverHello message for edge router, queuing again") + go func() { + strategy.routerConnectedQueue <- rtx + }() + } + } +} + +func (strategy *InstantStrategy) ReceiveResync(r *network.Router, hello *edge_ctrl_pb.RequestClientReSync) { + rtx := strategy.rtxMap.Get(r.Id) + + if rtx == nil { + pfxlog.Logger(). + WithField("strategy", strategy.Type()). + WithField("routerId", r.Id). + WithField("routerName", r.Name). + Error("received resync from router that is currently not tracked by the strategy, dropping resync") + return + } + + rtx.Status = env.RouterSyncResyncWait + + rtx.logger().WithField("strategy", strategy.Type()).Info("received resync from router, queuing") + + strategy.receivedClientHelloQueue <- rtx +} + +func (strategy *InstantStrategy) ReceiveClientHello(r *network.Router, respHello *edge_ctrl_pb.ClientHello) { + + rtx := strategy.rtxMap.Get(r.Id) + + if rtx == nil { + pfxlog.Logger(). + WithField("strategy", strategy.Type()). + WithField("routerId", r.Id). + WithField("routerName", r.Name). + Error("received hello from router that is currently not tracked by the strategy, dropping hello") + return + } + + rtx.Status = env.RouterSyncHelloWait + + logger := rtx.logger().WithField("strategy", strategy.Type()). + WithField("hostname", respHello.Hostname). + WithField("protocols", respHello.Protocols). + WithField("protocolPorts", respHello.ProtocolPorts). + WithField("data", respHello.Data) + + serverVersion := build.GetBuildInfo().Version() + + if r.VersionInfo != nil { + logger = logger.WithField("version", r.VersionInfo.Version). + WithField("revision", r.VersionInfo.Revision). + WithField("buildDate", r.VersionInfo.BuildDate). + WithField("os", r.VersionInfo.OS). + WithField("arch", r.VersionInfo.Arch) + } + + protocols := map[string]string{} + for _, p := range respHello.ProtocolPorts { + parts := strings.Split(p, ":") + ingressUrl := fmt.Sprintf("%s://%s:%s", parts[0], respHello.Hostname, parts[1]) + protocols[parts[0]] = ingressUrl + } + + rtx.EdgeRouter.Hostname = &respHello.Hostname + rtx.EdgeRouter.EdgeRouterProtocols = protocols + rtx.EdgeRouter.VersionInfo = r.VersionInfo + + logger.Infof("edge router sent hello with version [%s] to controller with version [%s]", respHello.Version, serverVersion) + strategy.receivedClientHelloQueue <- rtx +} + +func (strategy *InstantStrategy) synchronize(rtx *RouterSender) { + defer func() { + rtx.logger().WithField("strategy", strategy.Type()).Infof("exiting synchronization, final status: %s", rtx.Status) + }() + + if rtx.Router.Control.IsClosed() { + rtx.Status = env.RouterSyncDisconnected + rtx.logger().WithField("strategy", strategy.Type()).Error("attempting to start synchronization with edge router, but it has disconnected") + } + + rtx.Status = env.RouterSynInProgress + logger := rtx.logger().WithField("strategy", strategy.Type()) + logger.Info("started synchronizing edge router") + + chunkSize := 100 + strategy.ae.GetDbProvider().GetDb().View(func(tx *bbolt.Tx) error { + var apiSessions []*edge_ctrl_pb.ApiSession + + state := &InstantSyncState{ + Id: cuid.New(), + IsLast: true, + Sequence: 0, + } + + for cursor := strategy.ae.GetStores().ApiSession.IterateIds(tx, ast.BoolNodeTrue); cursor.IsValid(); cursor.Next() { + current := cursor.Current() + + apiSession, err := strategy.ae.GetStores().ApiSession.LoadOneById(tx, string(current)) + + if err != nil { + logger.WithError(err).WithField("apiSessionId", string(current)).Errorf("error querying api session [%s]: %v", string(current), err) + continue + } + + apiSessionProto, err := apiSessionToProto(strategy.ae, apiSession.Token, apiSession.IdentityId, apiSession.Id) + + if err != nil { + logger.WithError(err).WithField("apiSessionId", string(current)).Errorf("error turning apiSession [%s] into proto: %v", string(current), err) + continue + } + + apiSessions = append(apiSessions, apiSessionProto) + + if len(apiSessions) >= chunkSize { + state.IsLast = !cursor.IsValid() + strategy.sendApiSessionAdded(rtx, true, state, apiSessions) + + state.Sequence = state.Sequence + 1 + apiSessions = []*edge_ctrl_pb.ApiSession{} + } + } + + if len(apiSessions) > 0 { + state.IsLast = true + strategy.sendApiSessionAdded(rtx, true, state, apiSessions) + } + return nil + }) + + strategy.ae.GetDbProvider().GetDb().View(func(tx *bbolt.Tx) error { + var sessions []*edge_ctrl_pb.Session + + state := &InstantSyncState{ + Id: cuid.New(), + IsLast: true, + Sequence: 0, + } + + for cursor := strategy.ae.GetStores().Session.IterateIds(tx, ast.BoolNodeTrue); cursor.IsValid(); cursor.Next() { + current := cursor.Current() + + session, err := strategy.ae.GetStores().Session.LoadOneById(tx, string(current)) + + if err != nil { + logger.WithError(err).WithField("sessionId", string(current)).Errorf("error querying session [%s]: %v", string(current), err) + continue + } + + sessionProto, err := sessionToProto(strategy.ae, session) + + if err != nil { + logger.WithError(err).WithField("sessionId", string(current)).Errorf("error turning session [%s] into proto: %v", string(current), err) + continue + } + + sessions = append(sessions, sessionProto) + + if len(sessions) >= chunkSize { + state.IsLast = !cursor.IsValid() + strategy.sendSessionAdded(rtx, true, state, sessions) + + state.Sequence = state.Sequence + 1 + sessions = []*edge_ctrl_pb.Session{} + } + } + + if len(sessions) > 0 { + state.IsLast = true + strategy.sendSessionAdded(rtx, true, state, sessions) + } + return nil + }) + + rtx.Status = env.RouterSyncDone +} + +func (strategy *InstantStrategy) sendApiSessionAdded(rtx *RouterSender, isFullState bool, state *InstantSyncState, apiSessions []*edge_ctrl_pb.ApiSession) { + stateBytes, _ := json.Marshal(state) + + msgContent := &edge_ctrl_pb.ApiSessionAdded{ + IsFullState: isFullState, + ApiSessions: apiSessions, + } + + msgContentBytes, _ := proto.Marshal(msgContent) + + msg := channel2.NewMessage(env.ApiSessionAddedType, msgContentBytes) + + msg.Headers[env.SyncStrategyTypeHeader] = []byte(strategy.Type()) + msg.Headers[env.SyncStrategyStateHeader] = stateBytes + + rtx.Send(msg) +} + +func (strategy *InstantStrategy) sendSessionAdded(rtx *RouterSender, isFullState bool, state *InstantSyncState, sessions []*edge_ctrl_pb.Session) { + + stateBytes, _ := json.Marshal(state) + + msgContent := &edge_ctrl_pb.SessionAdded{ + IsFullState: isFullState, + Sessions: sessions, + } + + msgContentBytes, _ := proto.Marshal(msgContent) + + msg := channel2.NewMessage(env.SessionAddedType, msgContentBytes) + msg.Headers[env.SyncStrategyTypeHeader] = []byte(strategy.Type()) + msg.Headers[env.SyncStrategyStateHeader] = stateBytes + rtx.Send(msg) +} + +type InstantSyncState struct { + Id string `json:"id"` //unique id for the sync attempt + IsLast bool `json:"isLast"` // + Sequence int `json:"sequence"` //inreasing id from 0 per id for the +} diff --git a/go.mod b/go.mod index 2270fa4a5..9ee5717c2 100644 --- a/go.mod +++ b/go.mod @@ -32,6 +32,7 @@ require ( github.com/gorilla/handlers v1.5.1 github.com/jessevdk/go-flags v1.4.0 github.com/kataras/go-events v0.0.3-0.20201007151548-c411dc70c0a6 + github.com/lucsky/cuid v1.0.2 github.com/mdlayher/netlink v1.2.1 github.com/michaelquigley/pfxlog v0.3.6 github.com/miekg/dns v1.1.38 @@ -54,7 +55,7 @@ require ( golang.org/x/net v0.0.0-20210119194325-5f4716e94777 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061 - google.golang.org/protobuf v1.25.0 + google.golang.org/protobuf v1.25.0 // indirect gopkg.in/resty.v1 v1.12.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 diff --git a/go.sum b/go.sum index 2ad4344be..6dc2c353d 100644 --- a/go.sum +++ b/go.sum @@ -404,6 +404,8 @@ github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL github.com/lucas-clemente/quic-go v0.17.1/go.mod h1:I0+fcNTdb9eS1ZcjQZbDVPGchJ86chcIxPALn9lEJqE= github.com/lucas-clemente/quic-go v0.18.1 h1:DMR7guC0NtVS8zNZR3IO7NARZvZygkSC56GGtC6cyys= github.com/lucas-clemente/quic-go v0.18.1/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg= +github.com/lucsky/cuid v1.0.2 h1:z4XlExeoderxoPj2/dxKOyPxe9RCOu7yNq9/XWxIUMQ= +github.com/lucsky/cuid v1.0.2/go.mod h1:QaaJqckboimOmhRSJXSx/+IT+VTfxfPGSo/6mfgUfmE= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= diff --git a/pb/edge_ctrl_pb/edge_ctrl.pb.go b/pb/edge_ctrl_pb/edge_ctrl.pb.go index 4b7c7e8e8..a1d66033b 100644 --- a/pb/edge_ctrl_pb/edge_ctrl.pb.go +++ b/pb/edge_ctrl_pb/edge_ctrl.pb.go @@ -1,29 +1,24 @@ // Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.25.0 -// protoc v3.5.1 // source: edge_ctrl.proto package edge_ctrl_pb import ( + fmt "fmt" proto "github.com/golang/protobuf/proto" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" + math "math" ) -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package type ContentType int32 @@ -39,69 +34,51 @@ const ( ContentType_ApiSessionUpdatedType ContentType = 20201 ContentType_ApiSessionRemovedType ContentType = 20202 ContentType_ApiSessionHeartbeatType ContentType = 20203 + ContentType_RequestClientReSyncType ContentType = 20204 ContentType_EnrollType ContentType = 20300 ContentType_EnrollCertsType ContentType = 20301 ) -// Enum value maps for ContentType. -var ( - ContentType_name = map[int32]string{ - 0: "Zero", - 20000: "ServerHelloType", - 20001: "ClientHelloType", - 20002: "ErrorType", - 20100: "SessionAddedType", - 20101: "SessionUpdatedType", - 20102: "SessionRemovedType", - 20200: "ApiSessionAddedType", - 20201: "ApiSessionUpdatedType", - 20202: "ApiSessionRemovedType", - 20203: "ApiSessionHeartbeatType", - 20300: "EnrollType", - 20301: "EnrollCertsType", - } - ContentType_value = map[string]int32{ - "Zero": 0, - "ServerHelloType": 20000, - "ClientHelloType": 20001, - "ErrorType": 20002, - "SessionAddedType": 20100, - "SessionUpdatedType": 20101, - "SessionRemovedType": 20102, - "ApiSessionAddedType": 20200, - "ApiSessionUpdatedType": 20201, - "ApiSessionRemovedType": 20202, - "ApiSessionHeartbeatType": 20203, - "EnrollType": 20300, - "EnrollCertsType": 20301, - } -) +var ContentType_name = map[int32]string{ + 0: "Zero", + 20000: "ServerHelloType", + 20001: "ClientHelloType", + 20002: "ErrorType", + 20100: "SessionAddedType", + 20101: "SessionUpdatedType", + 20102: "SessionRemovedType", + 20200: "ApiSessionAddedType", + 20201: "ApiSessionUpdatedType", + 20202: "ApiSessionRemovedType", + 20203: "ApiSessionHeartbeatType", + 20204: "RequestClientReSyncType", + 20300: "EnrollType", + 20301: "EnrollCertsType", +} -func (x ContentType) Enum() *ContentType { - p := new(ContentType) - *p = x - return p +var ContentType_value = map[string]int32{ + "Zero": 0, + "ServerHelloType": 20000, + "ClientHelloType": 20001, + "ErrorType": 20002, + "SessionAddedType": 20100, + "SessionUpdatedType": 20101, + "SessionRemovedType": 20102, + "ApiSessionAddedType": 20200, + "ApiSessionUpdatedType": 20201, + "ApiSessionRemovedType": 20202, + "ApiSessionHeartbeatType": 20203, + "RequestClientReSyncType": 20204, + "EnrollType": 20300, + "EnrollCertsType": 20301, } func (x ContentType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) + return proto.EnumName(ContentType_name, int32(x)) } -func (ContentType) Descriptor() protoreflect.EnumDescriptor { - return file_edge_ctrl_proto_enumTypes[0].Descriptor() -} - -func (ContentType) Type() protoreflect.EnumType { - return &file_edge_ctrl_proto_enumTypes[0] -} - -func (x ContentType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use ContentType.Descriptor instead. func (ContentType) EnumDescriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{0} + return fileDescriptor_23f46a161f139ee1, []int{0} } type SessionType int32 @@ -111,2239 +88,828 @@ const ( SessionType_Bind SessionType = 1 ) -// Enum value maps for SessionType. -var ( - SessionType_name = map[int32]string{ - 0: "Dial", - 1: "Bind", - } - SessionType_value = map[string]int32{ - "Dial": 0, - "Bind": 1, - } -) +var SessionType_name = map[int32]string{ + 0: "Dial", + 1: "Bind", +} -func (x SessionType) Enum() *SessionType { - p := new(SessionType) - *p = x - return p +var SessionType_value = map[string]int32{ + "Dial": 0, + "Bind": 1, } func (x SessionType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) + return proto.EnumName(SessionType_name, int32(x)) } -func (SessionType) Descriptor() protoreflect.EnumDescriptor { - return file_edge_ctrl_proto_enumTypes[1].Descriptor() -} - -func (SessionType) Type() protoreflect.EnumType { - return &file_edge_ctrl_proto_enumTypes[1] -} - -func (x SessionType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use SessionType.Descriptor instead. func (SessionType) EnumDescriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{1} -} - -type PostureQuery_Type int32 - -const ( - PostureQuery_OS PostureQuery_Type = 0 - PostureQuery_MAC PostureQuery_Type = 10 - PostureQuery_WINDOWS_DOMAIN PostureQuery_Type = 20 - PostureQuery_PROCESS PostureQuery_Type = 30 -) - -// Enum value maps for PostureQuery_Type. -var ( - PostureQuery_Type_name = map[int32]string{ - 0: "OS", - 10: "MAC", - 20: "WINDOWS_DOMAIN", - 30: "PROCESS", - } - PostureQuery_Type_value = map[string]int32{ - "OS": 0, - "MAC": 10, - "WINDOWS_DOMAIN": 20, - "PROCESS": 30, - } -) - -func (x PostureQuery_Type) Enum() *PostureQuery_Type { - p := new(PostureQuery_Type) - *p = x - return p -} - -func (x PostureQuery_Type) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (PostureQuery_Type) Descriptor() protoreflect.EnumDescriptor { - return file_edge_ctrl_proto_enumTypes[2].Descriptor() -} - -func (PostureQuery_Type) Type() protoreflect.EnumType { - return &file_edge_ctrl_proto_enumTypes[2] -} - -func (x PostureQuery_Type) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use PostureQuery_Type.Descriptor instead. -func (PostureQuery_Type) EnumDescriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{13, 0} -} - -type PostureQuery_HashAlgorithm int32 - -const ( - PostureQuery_SHA512 PostureQuery_HashAlgorithm = 0 -) - -// Enum value maps for PostureQuery_HashAlgorithm. -var ( - PostureQuery_HashAlgorithm_name = map[int32]string{ - 0: "SHA512", - } - PostureQuery_HashAlgorithm_value = map[string]int32{ - "SHA512": 0, - } -) - -func (x PostureQuery_HashAlgorithm) Enum() *PostureQuery_HashAlgorithm { - p := new(PostureQuery_HashAlgorithm) - *p = x - return p -} - -func (x PostureQuery_HashAlgorithm) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (PostureQuery_HashAlgorithm) Descriptor() protoreflect.EnumDescriptor { - return file_edge_ctrl_proto_enumTypes[3].Descriptor() -} - -func (PostureQuery_HashAlgorithm) Type() protoreflect.EnumType { - return &file_edge_ctrl_proto_enumTypes[3] -} - -func (x PostureQuery_HashAlgorithm) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use PostureQuery_HashAlgorithm.Descriptor instead. -func (PostureQuery_HashAlgorithm) EnumDescriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{13, 1} -} - -type PostureResponse_Error_Code int32 - -const ( - PostureResponse_Error_UNKNOWN PostureResponse_Error_Code = 0 - PostureResponse_Error_UNSUPPORTED_QUERY_TYPE PostureResponse_Error_Code = 10 - PostureResponse_Error_UNSUPPORTED_HASH_ALGORITHM PostureResponse_Error_Code = 20 -) - -// Enum value maps for PostureResponse_Error_Code. -var ( - PostureResponse_Error_Code_name = map[int32]string{ - 0: "UNKNOWN", - 10: "UNSUPPORTED_QUERY_TYPE", - 20: "UNSUPPORTED_HASH_ALGORITHM", - } - PostureResponse_Error_Code_value = map[string]int32{ - "UNKNOWN": 0, - "UNSUPPORTED_QUERY_TYPE": 10, - "UNSUPPORTED_HASH_ALGORITHM": 20, - } -) - -func (x PostureResponse_Error_Code) Enum() *PostureResponse_Error_Code { - p := new(PostureResponse_Error_Code) - *p = x - return p -} - -func (x PostureResponse_Error_Code) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (PostureResponse_Error_Code) Descriptor() protoreflect.EnumDescriptor { - return file_edge_ctrl_proto_enumTypes[4].Descriptor() -} - -func (PostureResponse_Error_Code) Type() protoreflect.EnumType { - return &file_edge_ctrl_proto_enumTypes[4] -} - -func (x PostureResponse_Error_Code) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use PostureResponse_Error_Code.Descriptor instead. -func (PostureResponse_Error_Code) EnumDescriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{14, 0, 0} -} - -type PostureResponse_OperatingSystem_Type int32 - -const ( - PostureResponse_OperatingSystem_Android PostureResponse_OperatingSystem_Type = 0 - PostureResponse_OperatingSystem_iOS PostureResponse_OperatingSystem_Type = 10 - PostureResponse_OperatingSystem_Linux PostureResponse_OperatingSystem_Type = 20 - PostureResponse_OperatingSystem_macOS PostureResponse_OperatingSystem_Type = 30 - PostureResponse_OperatingSystem_Windows PostureResponse_OperatingSystem_Type = 40 - PostureResponse_OperatingSystem_WindowsServer PostureResponse_OperatingSystem_Type = 50 -) - -// Enum value maps for PostureResponse_OperatingSystem_Type. -var ( - PostureResponse_OperatingSystem_Type_name = map[int32]string{ - 0: "Android", - 10: "iOS", - 20: "Linux", - 30: "macOS", - 40: "Windows", - 50: "WindowsServer", - } - PostureResponse_OperatingSystem_Type_value = map[string]int32{ - "Android": 0, - "iOS": 10, - "Linux": 20, - "macOS": 30, - "Windows": 40, - "WindowsServer": 50, - } -) - -func (x PostureResponse_OperatingSystem_Type) Enum() *PostureResponse_OperatingSystem_Type { - p := new(PostureResponse_OperatingSystem_Type) - *p = x - return p -} - -func (x PostureResponse_OperatingSystem_Type) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (PostureResponse_OperatingSystem_Type) Descriptor() protoreflect.EnumDescriptor { - return file_edge_ctrl_proto_enumTypes[5].Descriptor() -} - -func (PostureResponse_OperatingSystem_Type) Type() protoreflect.EnumType { - return &file_edge_ctrl_proto_enumTypes[5] -} - -func (x PostureResponse_OperatingSystem_Type) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use PostureResponse_OperatingSystem_Type.Descriptor instead. -func (PostureResponse_OperatingSystem_Type) EnumDescriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{14, 4, 0} + return fileDescriptor_23f46a161f139ee1, []int{1} } type ServerHello struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` - Data map[string]string `protobuf:"bytes,2,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + Data map[string]string `protobuf:"bytes,2,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (x *ServerHello) Reset() { - *x = ServerHello{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ServerHello) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ServerHello) ProtoMessage() {} - -func (x *ServerHello) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ServerHello.ProtoReflect.Descriptor instead. +func (m *ServerHello) Reset() { *m = ServerHello{} } +func (m *ServerHello) String() string { return proto.CompactTextString(m) } +func (*ServerHello) ProtoMessage() {} func (*ServerHello) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{0} + return fileDescriptor_23f46a161f139ee1, []int{0} } -func (x *ServerHello) GetVersion() string { - if x != nil { - return x.Version +func (m *ServerHello) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ServerHello.Unmarshal(m, b) +} +func (m *ServerHello) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ServerHello.Marshal(b, m, deterministic) +} +func (m *ServerHello) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServerHello.Merge(m, src) +} +func (m *ServerHello) XXX_Size() int { + return xxx_messageInfo_ServerHello.Size(m) +} +func (m *ServerHello) XXX_DiscardUnknown() { + xxx_messageInfo_ServerHello.DiscardUnknown(m) +} + +var xxx_messageInfo_ServerHello proto.InternalMessageInfo + +func (m *ServerHello) GetVersion() string { + if m != nil { + return m.Version } return "" } -func (x *ServerHello) GetData() map[string]string { - if x != nil { - return x.Data +func (m *ServerHello) GetData() map[string]string { + if m != nil { + return m.Data } return nil } type ClientHello struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` - Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"` - Protocols []string `protobuf:"bytes,3,rep,name=protocols,proto3" json:"protocols,omitempty"` - Data map[string]string `protobuf:"bytes,4,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - ProtocolPorts []string `protobuf:"bytes,5,rep,name=protocolPorts,proto3" json:"protocolPorts,omitempty"` + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3" json:"hostname,omitempty"` + Protocols []string `protobuf:"bytes,3,rep,name=protocols,proto3" json:"protocols,omitempty"` + Data map[string]string `protobuf:"bytes,4,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + ProtocolPorts []string `protobuf:"bytes,5,rep,name=protocolPorts,proto3" json:"protocolPorts,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (x *ClientHello) Reset() { - *x = ClientHello{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ClientHello) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ClientHello) ProtoMessage() {} - -func (x *ClientHello) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ClientHello.ProtoReflect.Descriptor instead. +func (m *ClientHello) Reset() { *m = ClientHello{} } +func (m *ClientHello) String() string { return proto.CompactTextString(m) } +func (*ClientHello) ProtoMessage() {} func (*ClientHello) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{1} + return fileDescriptor_23f46a161f139ee1, []int{1} } -func (x *ClientHello) GetVersion() string { - if x != nil { - return x.Version +func (m *ClientHello) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ClientHello.Unmarshal(m, b) +} +func (m *ClientHello) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ClientHello.Marshal(b, m, deterministic) +} +func (m *ClientHello) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClientHello.Merge(m, src) +} +func (m *ClientHello) XXX_Size() int { + return xxx_messageInfo_ClientHello.Size(m) +} +func (m *ClientHello) XXX_DiscardUnknown() { + xxx_messageInfo_ClientHello.DiscardUnknown(m) +} + +var xxx_messageInfo_ClientHello proto.InternalMessageInfo + +func (m *ClientHello) GetVersion() string { + if m != nil { + return m.Version } return "" } -func (x *ClientHello) GetHostname() string { - if x != nil { - return x.Hostname +func (m *ClientHello) GetHostname() string { + if m != nil { + return m.Hostname } return "" } -func (x *ClientHello) GetProtocols() []string { - if x != nil { - return x.Protocols +func (m *ClientHello) GetProtocols() []string { + if m != nil { + return m.Protocols } return nil } -func (x *ClientHello) GetData() map[string]string { - if x != nil { - return x.Data +func (m *ClientHello) GetData() map[string]string { + if m != nil { + return m.Data } return nil } -func (x *ClientHello) GetProtocolPorts() []string { - if x != nil { - return x.ProtocolPorts +func (m *ClientHello) GetProtocolPorts() []string { + if m != nil { + return m.ProtocolPorts } return nil } type Error struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"` - Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` - Cause string `protobuf:"bytes,3,opt,name=cause,proto3" json:"cause,omitempty"` + Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Cause string `protobuf:"bytes,3,opt,name=cause,proto3" json:"cause,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (x *Error) Reset() { - *x = Error{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Error) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Error) ProtoMessage() {} - -func (x *Error) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Error.ProtoReflect.Descriptor instead. +func (m *Error) Reset() { *m = Error{} } +func (m *Error) String() string { return proto.CompactTextString(m) } +func (*Error) ProtoMessage() {} func (*Error) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{2} + return fileDescriptor_23f46a161f139ee1, []int{2} } -func (x *Error) GetCode() string { - if x != nil { - return x.Code +func (m *Error) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Error.Unmarshal(m, b) +} +func (m *Error) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Error.Marshal(b, m, deterministic) +} +func (m *Error) XXX_Merge(src proto.Message) { + xxx_messageInfo_Error.Merge(m, src) +} +func (m *Error) XXX_Size() int { + return xxx_messageInfo_Error.Size(m) +} +func (m *Error) XXX_DiscardUnknown() { + xxx_messageInfo_Error.DiscardUnknown(m) +} + +var xxx_messageInfo_Error proto.InternalMessageInfo + +func (m *Error) GetCode() string { + if m != nil { + return m.Code } return "" } -func (x *Error) GetMessage() string { - if x != nil { - return x.Message +func (m *Error) GetMessage() string { + if m != nil { + return m.Message } return "" } -func (x *Error) GetCause() string { - if x != nil { - return x.Cause +func (m *Error) GetCause() string { + if m != nil { + return m.Cause } return "" } type Service struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - EncryptionRequired bool `protobuf:"varint,3,opt,name=encryptionRequired,proto3" json:"encryptionRequired,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + EncryptionRequired bool `protobuf:"varint,3,opt,name=encryptionRequired,proto3" json:"encryptionRequired,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (x *Service) Reset() { - *x = Service{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Service) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Service) ProtoMessage() {} - -func (x *Service) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Service.ProtoReflect.Descriptor instead. +func (m *Service) Reset() { *m = Service{} } +func (m *Service) String() string { return proto.CompactTextString(m) } +func (*Service) ProtoMessage() {} func (*Service) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{3} + return fileDescriptor_23f46a161f139ee1, []int{3} } -func (x *Service) GetId() string { - if x != nil { - return x.Id +func (m *Service) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Service.Unmarshal(m, b) +} +func (m *Service) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Service.Marshal(b, m, deterministic) +} +func (m *Service) XXX_Merge(src proto.Message) { + xxx_messageInfo_Service.Merge(m, src) +} +func (m *Service) XXX_Size() int { + return xxx_messageInfo_Service.Size(m) +} +func (m *Service) XXX_DiscardUnknown() { + xxx_messageInfo_Service.DiscardUnknown(m) +} + +var xxx_messageInfo_Service proto.InternalMessageInfo + +func (m *Service) GetId() string { + if m != nil { + return m.Id } return "" } -func (x *Service) GetName() string { - if x != nil { - return x.Name +func (m *Service) GetName() string { + if m != nil { + return m.Name } return "" } -func (x *Service) GetEncryptionRequired() bool { - if x != nil { - return x.EncryptionRequired +func (m *Service) GetEncryptionRequired() bool { + if m != nil { + return m.EncryptionRequired } return false } type Session struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` - Type SessionType `protobuf:"varint,2,opt,name=type,proto3,enum=edge_ctrl.pb.SessionType" json:"type,omitempty"` - CertFingerprints []string `protobuf:"bytes,3,rep,name=certFingerprints,proto3" json:"certFingerprints,omitempty"` - Urls []string `protobuf:"bytes,4,rep,name=urls,proto3" json:"urls,omitempty"` - Service *Service `protobuf:"bytes,5,opt,name=service,proto3" json:"service,omitempty"` - Id string `protobuf:"bytes,7,opt,name=id,proto3" json:"id,omitempty"` - ApiSessionId string `protobuf:"bytes,8,opt,name=apiSessionId,proto3" json:"apiSessionId,omitempty"` + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + Type SessionType `protobuf:"varint,2,opt,name=type,proto3,enum=edge_ctrl.pb.SessionType" json:"type,omitempty"` + CertFingerprints []string `protobuf:"bytes,3,rep,name=certFingerprints,proto3" json:"certFingerprints,omitempty"` + Urls []string `protobuf:"bytes,4,rep,name=urls,proto3" json:"urls,omitempty"` + Service *Service `protobuf:"bytes,5,opt,name=service,proto3" json:"service,omitempty"` + Id string `protobuf:"bytes,7,opt,name=id,proto3" json:"id,omitempty"` + ApiSessionId string `protobuf:"bytes,8,opt,name=apiSessionId,proto3" json:"apiSessionId,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (x *Session) Reset() { - *x = Session{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Session) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Session) ProtoMessage() {} - -func (x *Session) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Session.ProtoReflect.Descriptor instead. +func (m *Session) Reset() { *m = Session{} } +func (m *Session) String() string { return proto.CompactTextString(m) } +func (*Session) ProtoMessage() {} func (*Session) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{4} + return fileDescriptor_23f46a161f139ee1, []int{4} } -func (x *Session) GetToken() string { - if x != nil { - return x.Token +func (m *Session) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Session.Unmarshal(m, b) +} +func (m *Session) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Session.Marshal(b, m, deterministic) +} +func (m *Session) XXX_Merge(src proto.Message) { + xxx_messageInfo_Session.Merge(m, src) +} +func (m *Session) XXX_Size() int { + return xxx_messageInfo_Session.Size(m) +} +func (m *Session) XXX_DiscardUnknown() { + xxx_messageInfo_Session.DiscardUnknown(m) +} + +var xxx_messageInfo_Session proto.InternalMessageInfo + +func (m *Session) GetToken() string { + if m != nil { + return m.Token } return "" } -func (x *Session) GetType() SessionType { - if x != nil { - return x.Type +func (m *Session) GetType() SessionType { + if m != nil { + return m.Type } return SessionType_Dial } -func (x *Session) GetCertFingerprints() []string { - if x != nil { - return x.CertFingerprints +func (m *Session) GetCertFingerprints() []string { + if m != nil { + return m.CertFingerprints } return nil } -func (x *Session) GetUrls() []string { - if x != nil { - return x.Urls +func (m *Session) GetUrls() []string { + if m != nil { + return m.Urls } return nil } -func (x *Session) GetService() *Service { - if x != nil { - return x.Service +func (m *Session) GetService() *Service { + if m != nil { + return m.Service } return nil } -func (x *Session) GetId() string { - if x != nil { - return x.Id +func (m *Session) GetId() string { + if m != nil { + return m.Id } return "" } -func (x *Session) GetApiSessionId() string { - if x != nil { - return x.ApiSessionId +func (m *Session) GetApiSessionId() string { + if m != nil { + return m.ApiSessionId } return "" } type ApiSession struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` - CertFingerprints []string `protobuf:"bytes,2,rep,name=certFingerprints,proto3" json:"certFingerprints,omitempty"` - Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"` + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + CertFingerprints []string `protobuf:"bytes,2,rep,name=certFingerprints,proto3" json:"certFingerprints,omitempty"` + Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (x *ApiSession) Reset() { - *x = ApiSession{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ApiSession) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ApiSession) ProtoMessage() {} - -func (x *ApiSession) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ApiSession.ProtoReflect.Descriptor instead. +func (m *ApiSession) Reset() { *m = ApiSession{} } +func (m *ApiSession) String() string { return proto.CompactTextString(m) } +func (*ApiSession) ProtoMessage() {} func (*ApiSession) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{5} + return fileDescriptor_23f46a161f139ee1, []int{5} } -func (x *ApiSession) GetToken() string { - if x != nil { - return x.Token +func (m *ApiSession) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ApiSession.Unmarshal(m, b) +} +func (m *ApiSession) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ApiSession.Marshal(b, m, deterministic) +} +func (m *ApiSession) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApiSession.Merge(m, src) +} +func (m *ApiSession) XXX_Size() int { + return xxx_messageInfo_ApiSession.Size(m) +} +func (m *ApiSession) XXX_DiscardUnknown() { + xxx_messageInfo_ApiSession.DiscardUnknown(m) +} + +var xxx_messageInfo_ApiSession proto.InternalMessageInfo + +func (m *ApiSession) GetToken() string { + if m != nil { + return m.Token } return "" } -func (x *ApiSession) GetCertFingerprints() []string { - if x != nil { - return x.CertFingerprints +func (m *ApiSession) GetCertFingerprints() []string { + if m != nil { + return m.CertFingerprints } return nil } -func (x *ApiSession) GetId() string { - if x != nil { - return x.Id +func (m *ApiSession) GetId() string { + if m != nil { + return m.Id } return "" } type ApiSessionAdded struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - IsFullState bool `protobuf:"varint,1,opt,name=isFullState,proto3" json:"isFullState,omitempty"` - ApiSessions []*ApiSession `protobuf:"bytes,2,rep,name=apiSessions,proto3" json:"apiSessions,omitempty"` + IsFullState bool `protobuf:"varint,1,opt,name=isFullState,proto3" json:"isFullState,omitempty"` + ApiSessions []*ApiSession `protobuf:"bytes,2,rep,name=apiSessions,proto3" json:"apiSessions,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (x *ApiSessionAdded) Reset() { - *x = ApiSessionAdded{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ApiSessionAdded) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ApiSessionAdded) ProtoMessage() {} - -func (x *ApiSessionAdded) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ApiSessionAdded.ProtoReflect.Descriptor instead. +func (m *ApiSessionAdded) Reset() { *m = ApiSessionAdded{} } +func (m *ApiSessionAdded) String() string { return proto.CompactTextString(m) } +func (*ApiSessionAdded) ProtoMessage() {} func (*ApiSessionAdded) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{6} + return fileDescriptor_23f46a161f139ee1, []int{6} } -func (x *ApiSessionAdded) GetIsFullState() bool { - if x != nil { - return x.IsFullState +func (m *ApiSessionAdded) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ApiSessionAdded.Unmarshal(m, b) +} +func (m *ApiSessionAdded) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ApiSessionAdded.Marshal(b, m, deterministic) +} +func (m *ApiSessionAdded) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApiSessionAdded.Merge(m, src) +} +func (m *ApiSessionAdded) XXX_Size() int { + return xxx_messageInfo_ApiSessionAdded.Size(m) +} +func (m *ApiSessionAdded) XXX_DiscardUnknown() { + xxx_messageInfo_ApiSessionAdded.DiscardUnknown(m) +} + +var xxx_messageInfo_ApiSessionAdded proto.InternalMessageInfo + +func (m *ApiSessionAdded) GetIsFullState() bool { + if m != nil { + return m.IsFullState } return false } -func (x *ApiSessionAdded) GetApiSessions() []*ApiSession { - if x != nil { - return x.ApiSessions +func (m *ApiSessionAdded) GetApiSessions() []*ApiSession { + if m != nil { + return m.ApiSessions } return nil } type ApiSessionUpdated struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ApiSessions []*ApiSession `protobuf:"bytes,1,rep,name=apiSessions,proto3" json:"apiSessions,omitempty"` + ApiSessions []*ApiSession `protobuf:"bytes,1,rep,name=apiSessions,proto3" json:"apiSessions,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (x *ApiSessionUpdated) Reset() { - *x = ApiSessionUpdated{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ApiSessionUpdated) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ApiSessionUpdated) ProtoMessage() {} - -func (x *ApiSessionUpdated) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ApiSessionUpdated.ProtoReflect.Descriptor instead. +func (m *ApiSessionUpdated) Reset() { *m = ApiSessionUpdated{} } +func (m *ApiSessionUpdated) String() string { return proto.CompactTextString(m) } +func (*ApiSessionUpdated) ProtoMessage() {} func (*ApiSessionUpdated) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{7} + return fileDescriptor_23f46a161f139ee1, []int{7} } -func (x *ApiSessionUpdated) GetApiSessions() []*ApiSession { - if x != nil { - return x.ApiSessions +func (m *ApiSessionUpdated) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ApiSessionUpdated.Unmarshal(m, b) +} +func (m *ApiSessionUpdated) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ApiSessionUpdated.Marshal(b, m, deterministic) +} +func (m *ApiSessionUpdated) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApiSessionUpdated.Merge(m, src) +} +func (m *ApiSessionUpdated) XXX_Size() int { + return xxx_messageInfo_ApiSessionUpdated.Size(m) +} +func (m *ApiSessionUpdated) XXX_DiscardUnknown() { + xxx_messageInfo_ApiSessionUpdated.DiscardUnknown(m) +} + +var xxx_messageInfo_ApiSessionUpdated proto.InternalMessageInfo + +func (m *ApiSessionUpdated) GetApiSessions() []*ApiSession { + if m != nil { + return m.ApiSessions } return nil } type ApiSessionRemoved struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Tokens []string `protobuf:"bytes,1,rep,name=tokens,proto3" json:"tokens,omitempty"` + Tokens []string `protobuf:"bytes,1,rep,name=tokens,proto3" json:"tokens,omitempty"` + Ids []string `protobuf:"bytes,2,rep,name=ids,proto3" json:"ids,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (x *ApiSessionRemoved) Reset() { - *x = ApiSessionRemoved{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ApiSessionRemoved) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ApiSessionRemoved) ProtoMessage() {} - -func (x *ApiSessionRemoved) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ApiSessionRemoved.ProtoReflect.Descriptor instead. +func (m *ApiSessionRemoved) Reset() { *m = ApiSessionRemoved{} } +func (m *ApiSessionRemoved) String() string { return proto.CompactTextString(m) } +func (*ApiSessionRemoved) ProtoMessage() {} func (*ApiSessionRemoved) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{8} + return fileDescriptor_23f46a161f139ee1, []int{8} } -func (x *ApiSessionRemoved) GetTokens() []string { - if x != nil { - return x.Tokens +func (m *ApiSessionRemoved) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ApiSessionRemoved.Unmarshal(m, b) +} +func (m *ApiSessionRemoved) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ApiSessionRemoved.Marshal(b, m, deterministic) +} +func (m *ApiSessionRemoved) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApiSessionRemoved.Merge(m, src) +} +func (m *ApiSessionRemoved) XXX_Size() int { + return xxx_messageInfo_ApiSessionRemoved.Size(m) +} +func (m *ApiSessionRemoved) XXX_DiscardUnknown() { + xxx_messageInfo_ApiSessionRemoved.DiscardUnknown(m) +} + +var xxx_messageInfo_ApiSessionRemoved proto.InternalMessageInfo + +func (m *ApiSessionRemoved) GetTokens() []string { + if m != nil { + return m.Tokens + } + return nil +} + +func (m *ApiSessionRemoved) GetIds() []string { + if m != nil { + return m.Ids } return nil } type ApiSessionHeartbeat struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Tokens []string `protobuf:"bytes,1,rep,name=tokens,proto3" json:"tokens,omitempty"` + Tokens []string `protobuf:"bytes,1,rep,name=tokens,proto3" json:"tokens,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (x *ApiSessionHeartbeat) Reset() { - *x = ApiSessionHeartbeat{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ApiSessionHeartbeat) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ApiSessionHeartbeat) ProtoMessage() {} - -func (x *ApiSessionHeartbeat) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ApiSessionHeartbeat.ProtoReflect.Descriptor instead. +func (m *ApiSessionHeartbeat) Reset() { *m = ApiSessionHeartbeat{} } +func (m *ApiSessionHeartbeat) String() string { return proto.CompactTextString(m) } +func (*ApiSessionHeartbeat) ProtoMessage() {} func (*ApiSessionHeartbeat) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{9} + return fileDescriptor_23f46a161f139ee1, []int{9} } -func (x *ApiSessionHeartbeat) GetTokens() []string { - if x != nil { - return x.Tokens +func (m *ApiSessionHeartbeat) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ApiSessionHeartbeat.Unmarshal(m, b) +} +func (m *ApiSessionHeartbeat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ApiSessionHeartbeat.Marshal(b, m, deterministic) +} +func (m *ApiSessionHeartbeat) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApiSessionHeartbeat.Merge(m, src) +} +func (m *ApiSessionHeartbeat) XXX_Size() int { + return xxx_messageInfo_ApiSessionHeartbeat.Size(m) +} +func (m *ApiSessionHeartbeat) XXX_DiscardUnknown() { + xxx_messageInfo_ApiSessionHeartbeat.DiscardUnknown(m) +} + +var xxx_messageInfo_ApiSessionHeartbeat proto.InternalMessageInfo + +func (m *ApiSessionHeartbeat) GetTokens() []string { + if m != nil { + return m.Tokens } return nil } type SessionAdded struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - IsFullState bool `protobuf:"varint,1,opt,name=isFullState,proto3" json:"isFullState,omitempty"` - Sessions []*Session `protobuf:"bytes,2,rep,name=sessions,proto3" json:"sessions,omitempty"` + IsFullState bool `protobuf:"varint,1,opt,name=isFullState,proto3" json:"isFullState,omitempty"` + Sessions []*Session `protobuf:"bytes,2,rep,name=sessions,proto3" json:"sessions,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (x *SessionAdded) Reset() { - *x = SessionAdded{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SessionAdded) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SessionAdded) ProtoMessage() {} - -func (x *SessionAdded) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SessionAdded.ProtoReflect.Descriptor instead. +func (m *SessionAdded) Reset() { *m = SessionAdded{} } +func (m *SessionAdded) String() string { return proto.CompactTextString(m) } +func (*SessionAdded) ProtoMessage() {} func (*SessionAdded) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{10} + return fileDescriptor_23f46a161f139ee1, []int{10} } -func (x *SessionAdded) GetIsFullState() bool { - if x != nil { - return x.IsFullState +func (m *SessionAdded) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SessionAdded.Unmarshal(m, b) +} +func (m *SessionAdded) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SessionAdded.Marshal(b, m, deterministic) +} +func (m *SessionAdded) XXX_Merge(src proto.Message) { + xxx_messageInfo_SessionAdded.Merge(m, src) +} +func (m *SessionAdded) XXX_Size() int { + return xxx_messageInfo_SessionAdded.Size(m) +} +func (m *SessionAdded) XXX_DiscardUnknown() { + xxx_messageInfo_SessionAdded.DiscardUnknown(m) +} + +var xxx_messageInfo_SessionAdded proto.InternalMessageInfo + +func (m *SessionAdded) GetIsFullState() bool { + if m != nil { + return m.IsFullState } return false } -func (x *SessionAdded) GetSessions() []*Session { - if x != nil { - return x.Sessions +func (m *SessionAdded) GetSessions() []*Session { + if m != nil { + return m.Sessions } return nil } type SessionRemoved struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Tokens []string `protobuf:"bytes,1,rep,name=tokens,proto3" json:"tokens,omitempty"` + Tokens []string `protobuf:"bytes,1,rep,name=tokens,proto3" json:"tokens,omitempty"` + Ids []string `protobuf:"bytes,2,rep,name=ids,proto3" json:"ids,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (x *SessionRemoved) Reset() { - *x = SessionRemoved{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SessionRemoved) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SessionRemoved) ProtoMessage() {} - -func (x *SessionRemoved) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SessionRemoved.ProtoReflect.Descriptor instead. +func (m *SessionRemoved) Reset() { *m = SessionRemoved{} } +func (m *SessionRemoved) String() string { return proto.CompactTextString(m) } +func (*SessionRemoved) ProtoMessage() {} func (*SessionRemoved) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{11} + return fileDescriptor_23f46a161f139ee1, []int{11} } -func (x *SessionRemoved) GetTokens() []string { - if x != nil { - return x.Tokens +func (m *SessionRemoved) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SessionRemoved.Unmarshal(m, b) +} +func (m *SessionRemoved) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SessionRemoved.Marshal(b, m, deterministic) +} +func (m *SessionRemoved) XXX_Merge(src proto.Message) { + xxx_messageInfo_SessionRemoved.Merge(m, src) +} +func (m *SessionRemoved) XXX_Size() int { + return xxx_messageInfo_SessionRemoved.Size(m) +} +func (m *SessionRemoved) XXX_DiscardUnknown() { + xxx_messageInfo_SessionRemoved.DiscardUnknown(m) +} + +var xxx_messageInfo_SessionRemoved proto.InternalMessageInfo + +func (m *SessionRemoved) GetTokens() []string { + if m != nil { + return m.Tokens + } + return nil +} + +func (m *SessionRemoved) GetIds() []string { + if m != nil { + return m.Ids } return nil } type SessionUpdated struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` - Urls []string `protobuf:"bytes,2,rep,name=urls,proto3" json:"urls,omitempty"` - Service *Service `protobuf:"bytes,3,opt,name=service,proto3" json:"service,omitempty"` + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + Urls []string `protobuf:"bytes,2,rep,name=urls,proto3" json:"urls,omitempty"` + Service *Service `protobuf:"bytes,3,opt,name=service,proto3" json:"service,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (x *SessionUpdated) Reset() { - *x = SessionUpdated{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SessionUpdated) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SessionUpdated) ProtoMessage() {} - -func (x *SessionUpdated) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SessionUpdated.ProtoReflect.Descriptor instead. +func (m *SessionUpdated) Reset() { *m = SessionUpdated{} } +func (m *SessionUpdated) String() string { return proto.CompactTextString(m) } +func (*SessionUpdated) ProtoMessage() {} func (*SessionUpdated) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{12} + return fileDescriptor_23f46a161f139ee1, []int{12} } -func (x *SessionUpdated) GetToken() string { - if x != nil { - return x.Token - } - return "" +func (m *SessionUpdated) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SessionUpdated.Unmarshal(m, b) +} +func (m *SessionUpdated) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SessionUpdated.Marshal(b, m, deterministic) +} +func (m *SessionUpdated) XXX_Merge(src proto.Message) { + xxx_messageInfo_SessionUpdated.Merge(m, src) +} +func (m *SessionUpdated) XXX_Size() int { + return xxx_messageInfo_SessionUpdated.Size(m) +} +func (m *SessionUpdated) XXX_DiscardUnknown() { + xxx_messageInfo_SessionUpdated.DiscardUnknown(m) } -func (x *SessionUpdated) GetUrls() []string { - if x != nil { - return x.Urls - } - return nil -} +var xxx_messageInfo_SessionUpdated proto.InternalMessageInfo -func (x *SessionUpdated) GetService() *Service { - if x != nil { - return x.Service - } - return nil -} - -type PostureQuery struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - PostureCheckId string `protobuf:"bytes,20,opt,name=postureCheckId,proto3" json:"postureCheckId,omitempty"` - DisplayName string `protobuf:"bytes,30,opt,name=displayName,proto3" json:"displayName,omitempty"` - Type PostureQuery_Type `protobuf:"varint,40,opt,name=type,proto3,enum=edge_ctrl.pb.PostureQuery_Type" json:"type,omitempty"` - Version string `protobuf:"bytes,50,opt,name=version,proto3" json:"version,omitempty"` - // Types that are assignable to Parameters: - // *PostureQuery_Na - // *PostureQuery_Process_ - Parameters isPostureQuery_Parameters `protobuf_oneof:"parameters"` -} - -func (x *PostureQuery) Reset() { - *x = PostureQuery{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PostureQuery) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PostureQuery) ProtoMessage() {} - -func (x *PostureQuery) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PostureQuery.ProtoReflect.Descriptor instead. -func (*PostureQuery) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{13} -} - -func (x *PostureQuery) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *PostureQuery) GetPostureCheckId() string { - if x != nil { - return x.PostureCheckId - } - return "" -} - -func (x *PostureQuery) GetDisplayName() string { - if x != nil { - return x.DisplayName - } - return "" -} - -func (x *PostureQuery) GetType() PostureQuery_Type { - if x != nil { - return x.Type - } - return PostureQuery_OS -} - -func (x *PostureQuery) GetVersion() string { - if x != nil { - return x.Version - } - return "" -} - -func (m *PostureQuery) GetParameters() isPostureQuery_Parameters { +func (m *SessionUpdated) GetToken() string { if m != nil { - return m.Parameters - } - return nil -} - -func (x *PostureQuery) GetNa() *PostureQuery_None { - if x, ok := x.GetParameters().(*PostureQuery_Na); ok { - return x.Na - } - return nil -} - -func (x *PostureQuery) GetProcess() *PostureQuery_Process { - if x, ok := x.GetParameters().(*PostureQuery_Process_); ok { - return x.Process - } - return nil -} - -type isPostureQuery_Parameters interface { - isPostureQuery_Parameters() -} - -type PostureQuery_Na struct { - Na *PostureQuery_None `protobuf:"bytes,60,opt,name=na,proto3,oneof"` -} - -type PostureQuery_Process_ struct { - Process *PostureQuery_Process `protobuf:"bytes,70,opt,name=process,proto3,oneof"` -} - -func (*PostureQuery_Na) isPostureQuery_Parameters() {} - -func (*PostureQuery_Process_) isPostureQuery_Parameters() {} - -type PostureResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // Types that are assignable to Payload: - // *PostureResponse_Error_ - // *PostureResponse_Process - // *PostureResponse_Mac - // *PostureResponse_Domain - // *PostureResponse_Os - Payload isPostureResponse_Payload `protobuf_oneof:"payload"` -} - -func (x *PostureResponse) Reset() { - *x = PostureResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PostureResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PostureResponse) ProtoMessage() {} - -func (x *PostureResponse) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PostureResponse.ProtoReflect.Descriptor instead. -func (*PostureResponse) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{14} -} - -func (x *PostureResponse) GetId() string { - if x != nil { - return x.Id + return m.Token } return "" } -func (m *PostureResponse) GetPayload() isPostureResponse_Payload { +func (m *SessionUpdated) GetUrls() []string { if m != nil { - return m.Payload + return m.Urls } return nil } -func (x *PostureResponse) GetError() *PostureResponse_Error { - if x, ok := x.GetPayload().(*PostureResponse_Error_); ok { - return x.Error +func (m *SessionUpdated) GetService() *Service { + if m != nil { + return m.Service } return nil } -func (x *PostureResponse) GetProcess() *PostureResponse_Proc { - if x, ok := x.GetPayload().(*PostureResponse_Process); ok { - return x.Process - } - return nil +type RequestClientReSync struct { + Reason string `protobuf:"bytes,1,opt,name=reason,proto3" json:"reason,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (x *PostureResponse) GetMac() *PostureResponse_MacAddresses { - if x, ok := x.GetPayload().(*PostureResponse_Mac); ok { - return x.Mac - } - return nil +func (m *RequestClientReSync) Reset() { *m = RequestClientReSync{} } +func (m *RequestClientReSync) String() string { return proto.CompactTextString(m) } +func (*RequestClientReSync) ProtoMessage() {} +func (*RequestClientReSync) Descriptor() ([]byte, []int) { + return fileDescriptor_23f46a161f139ee1, []int{13} } -func (x *PostureResponse) GetDomain() *PostureResponse_WindowsDomain { - if x, ok := x.GetPayload().(*PostureResponse_Domain); ok { - return x.Domain - } - return nil +func (m *RequestClientReSync) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RequestClientReSync.Unmarshal(m, b) +} +func (m *RequestClientReSync) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RequestClientReSync.Marshal(b, m, deterministic) +} +func (m *RequestClientReSync) XXX_Merge(src proto.Message) { + xxx_messageInfo_RequestClientReSync.Merge(m, src) +} +func (m *RequestClientReSync) XXX_Size() int { + return xxx_messageInfo_RequestClientReSync.Size(m) +} +func (m *RequestClientReSync) XXX_DiscardUnknown() { + xxx_messageInfo_RequestClientReSync.DiscardUnknown(m) } -func (x *PostureResponse) GetOs() *PostureResponse_OperatingSystem { - if x, ok := x.GetPayload().(*PostureResponse_Os); ok { - return x.Os - } - return nil -} +var xxx_messageInfo_RequestClientReSync proto.InternalMessageInfo -type isPostureResponse_Payload interface { - isPostureResponse_Payload() -} - -type PostureResponse_Error_ struct { - Error *PostureResponse_Error `protobuf:"bytes,20,opt,name=error,proto3,oneof"` -} - -type PostureResponse_Process struct { - Process *PostureResponse_Proc `protobuf:"bytes,30,opt,name=process,proto3,oneof"` -} - -type PostureResponse_Mac struct { - Mac *PostureResponse_MacAddresses `protobuf:"bytes,40,opt,name=mac,proto3,oneof"` -} - -type PostureResponse_Domain struct { - Domain *PostureResponse_WindowsDomain `protobuf:"bytes,50,opt,name=domain,proto3,oneof"` -} - -type PostureResponse_Os struct { - Os *PostureResponse_OperatingSystem `protobuf:"bytes,60,opt,name=os,proto3,oneof"` -} - -func (*PostureResponse_Error_) isPostureResponse_Payload() {} - -func (*PostureResponse_Process) isPostureResponse_Payload() {} - -func (*PostureResponse_Mac) isPostureResponse_Payload() {} - -func (*PostureResponse_Domain) isPostureResponse_Payload() {} - -func (*PostureResponse_Os) isPostureResponse_Payload() {} - -type PostureQuery_None struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *PostureQuery_None) Reset() { - *x = PostureQuery_None{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PostureQuery_None) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PostureQuery_None) ProtoMessage() {} - -func (x *PostureQuery_None) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PostureQuery_None.ProtoReflect.Descriptor instead. -func (*PostureQuery_None) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{13, 0} -} - -type PostureQuery_Process struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Paths []string `protobuf:"bytes,1,rep,name=paths,proto3" json:"paths,omitempty"` - HashAlgorithm PostureQuery_HashAlgorithm `protobuf:"varint,10,opt,name=hashAlgorithm,proto3,enum=edge_ctrl.pb.PostureQuery_HashAlgorithm" json:"hashAlgorithm,omitempty"` -} - -func (x *PostureQuery_Process) Reset() { - *x = PostureQuery_Process{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PostureQuery_Process) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PostureQuery_Process) ProtoMessage() {} - -func (x *PostureQuery_Process) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PostureQuery_Process.ProtoReflect.Descriptor instead. -func (*PostureQuery_Process) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{13, 1} -} - -func (x *PostureQuery_Process) GetPaths() []string { - if x != nil { - return x.Paths - } - return nil -} - -func (x *PostureQuery_Process) GetHashAlgorithm() PostureQuery_HashAlgorithm { - if x != nil { - return x.HashAlgorithm - } - return PostureQuery_SHA512 -} - -type PostureResponse_Error struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Code PostureResponse_Error_Code `protobuf:"varint,1,opt,name=code,proto3,enum=edge_ctrl.pb.PostureResponse_Error_Code" json:"code,omitempty"` - Message string `protobuf:"bytes,10,opt,name=message,proto3" json:"message,omitempty"` - Data map[string]string `protobuf:"bytes,20,rep,name=data,proto3" json:"data,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *PostureResponse_Error) Reset() { - *x = PostureResponse_Error{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PostureResponse_Error) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PostureResponse_Error) ProtoMessage() {} - -func (x *PostureResponse_Error) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PostureResponse_Error.ProtoReflect.Descriptor instead. -func (*PostureResponse_Error) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{14, 0} -} - -func (x *PostureResponse_Error) GetCode() PostureResponse_Error_Code { - if x != nil { - return x.Code - } - return PostureResponse_Error_UNKNOWN -} - -func (x *PostureResponse_Error) GetMessage() string { - if x != nil { - return x.Message +func (m *RequestClientReSync) GetReason() string { + if m != nil { + return m.Reason } return "" } -func (x *PostureResponse_Error) GetData() map[string]string { - if x != nil { - return x.Data - } - return nil +func init() { + proto.RegisterEnum("edge_ctrl.pb.ContentType", ContentType_name, ContentType_value) + proto.RegisterEnum("edge_ctrl.pb.SessionType", SessionType_name, SessionType_value) + proto.RegisterType((*ServerHello)(nil), "edge_ctrl.pb.ServerHello") + proto.RegisterMapType((map[string]string)(nil), "edge_ctrl.pb.ServerHello.DataEntry") + proto.RegisterType((*ClientHello)(nil), "edge_ctrl.pb.ClientHello") + proto.RegisterMapType((map[string]string)(nil), "edge_ctrl.pb.ClientHello.DataEntry") + proto.RegisterType((*Error)(nil), "edge_ctrl.pb.Error") + proto.RegisterType((*Service)(nil), "edge_ctrl.pb.Service") + proto.RegisterType((*Session)(nil), "edge_ctrl.pb.Session") + proto.RegisterType((*ApiSession)(nil), "edge_ctrl.pb.ApiSession") + proto.RegisterType((*ApiSessionAdded)(nil), "edge_ctrl.pb.ApiSessionAdded") + proto.RegisterType((*ApiSessionUpdated)(nil), "edge_ctrl.pb.ApiSessionUpdated") + proto.RegisterType((*ApiSessionRemoved)(nil), "edge_ctrl.pb.ApiSessionRemoved") + proto.RegisterType((*ApiSessionHeartbeat)(nil), "edge_ctrl.pb.ApiSessionHeartbeat") + proto.RegisterType((*SessionAdded)(nil), "edge_ctrl.pb.SessionAdded") + proto.RegisterType((*SessionRemoved)(nil), "edge_ctrl.pb.SessionRemoved") + proto.RegisterType((*SessionUpdated)(nil), "edge_ctrl.pb.SessionUpdated") + proto.RegisterType((*RequestClientReSync)(nil), "edge_ctrl.pb.RequestClientReSync") } -type PostureResponse_Proc struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - BinaryHash string `protobuf:"bytes,1,opt,name=binaryHash,proto3" json:"binaryHash,omitempty"` - SignerFingerprint string `protobuf:"bytes,10,opt,name=signerFingerprint,proto3" json:"signerFingerprint,omitempty"` +func init() { + proto.RegisterFile("edge_ctrl.proto", fileDescriptor_23f46a161f139ee1) } -func (x *PostureResponse_Proc) Reset() { - *x = PostureResponse_Proc{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PostureResponse_Proc) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PostureResponse_Proc) ProtoMessage() {} - -func (x *PostureResponse_Proc) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[20] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PostureResponse_Proc.ProtoReflect.Descriptor instead. -func (*PostureResponse_Proc) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{14, 1} -} - -func (x *PostureResponse_Proc) GetBinaryHash() string { - if x != nil { - return x.BinaryHash - } - return "" -} - -func (x *PostureResponse_Proc) GetSignerFingerprint() string { - if x != nil { - return x.SignerFingerprint - } - return "" -} - -type PostureResponse_MacAddresses struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Addresses []string `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty"` -} - -func (x *PostureResponse_MacAddresses) Reset() { - *x = PostureResponse_MacAddresses{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PostureResponse_MacAddresses) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PostureResponse_MacAddresses) ProtoMessage() {} - -func (x *PostureResponse_MacAddresses) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[21] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PostureResponse_MacAddresses.ProtoReflect.Descriptor instead. -func (*PostureResponse_MacAddresses) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{14, 2} -} - -func (x *PostureResponse_MacAddresses) GetAddresses() []string { - if x != nil { - return x.Addresses - } - return nil -} - -type PostureResponse_WindowsDomain struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` -} - -func (x *PostureResponse_WindowsDomain) Reset() { - *x = PostureResponse_WindowsDomain{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PostureResponse_WindowsDomain) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PostureResponse_WindowsDomain) ProtoMessage() {} - -func (x *PostureResponse_WindowsDomain) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[22] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PostureResponse_WindowsDomain.ProtoReflect.Descriptor instead. -func (*PostureResponse_WindowsDomain) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{14, 3} -} - -func (x *PostureResponse_WindowsDomain) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -type PostureResponse_OperatingSystem struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Type PostureResponse_OperatingSystem_Type `protobuf:"varint,1,opt,name=type,proto3,enum=edge_ctrl.pb.PostureResponse_OperatingSystem_Type" json:"type,omitempty"` - Version string `protobuf:"bytes,10,opt,name=version,proto3" json:"version,omitempty"` - Build string `protobuf:"bytes,20,opt,name=build,proto3" json:"build,omitempty"` -} - -func (x *PostureResponse_OperatingSystem) Reset() { - *x = PostureResponse_OperatingSystem{} - if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PostureResponse_OperatingSystem) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PostureResponse_OperatingSystem) ProtoMessage() {} - -func (x *PostureResponse_OperatingSystem) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[23] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PostureResponse_OperatingSystem.ProtoReflect.Descriptor instead. -func (*PostureResponse_OperatingSystem) Descriptor() ([]byte, []int) { - return file_edge_ctrl_proto_rawDescGZIP(), []int{14, 4} -} - -func (x *PostureResponse_OperatingSystem) GetType() PostureResponse_OperatingSystem_Type { - if x != nil { - return x.Type - } - return PostureResponse_OperatingSystem_Android -} - -func (x *PostureResponse_OperatingSystem) GetVersion() string { - if x != nil { - return x.Version - } - return "" -} - -func (x *PostureResponse_OperatingSystem) GetBuild() string { - if x != nil { - return x.Build - } - return "" -} - -var File_edge_ctrl_proto protoreflect.FileDescriptor - -var file_edge_ctrl_proto_rawDesc = []byte{ - 0x0a, 0x0f, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x0c, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x22, - 0x99, 0x01, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, - 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x04, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, - 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x65, 0x6c, - 0x6c, 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x64, 0x61, - 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 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, 0xf9, 0x01, 0x0a, 0x0b, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x12, - 0x37, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, - 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x24, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x1a, 0x37, - 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 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, 0x4b, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x63, 0x61, 0x75, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, - 0x61, 0x75, 0x73, 0x65, 0x22, 0x5d, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x12, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x64, 0x22, 0xf3, 0x01, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, - 0x70, 0x62, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x65, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x67, - 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, - 0x63, 0x65, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x73, - 0x12, 0x12, 0x0a, 0x04, 0x75, 0x72, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, - 0x75, 0x72, 0x6c, 0x73, 0x12, 0x2f, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, - 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x70, 0x69, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x5e, 0x0a, 0x0a, 0x41, 0x70, 0x69, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2a, 0x0a, - 0x10, 0x63, 0x65, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x63, 0x65, 0x72, 0x74, 0x46, 0x69, 0x6e, - 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x6f, 0x0a, 0x0f, 0x41, 0x70, 0x69, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, - 0x69, 0x73, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0b, 0x69, 0x73, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3a, - 0x0a, 0x0b, 0x61, 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, - 0x70, 0x62, 0x2e, 0x41, 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x61, - 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x4f, 0x0a, 0x11, 0x41, 0x70, - 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, - 0x3a, 0x0a, 0x0b, 0x61, 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, - 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, - 0x61, 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x2b, 0x0a, 0x11, 0x41, - 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, - 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x2d, 0x0a, 0x13, 0x41, 0x70, 0x69, 0x53, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, - 0x16, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x63, 0x0a, 0x0c, 0x53, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x73, 0x46, 0x75, 0x6c, - 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, - 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x73, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x65, 0x64, - 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x08, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x28, 0x0a, 0x0e, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x12, 0x16, - 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x6b, 0x0a, 0x0e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x12, - 0x0a, 0x04, 0x75, 0x72, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x75, 0x72, - 0x6c, 0x73, 0x12, 0x2f, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, - 0x70, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x22, 0x88, 0x04, 0x0a, 0x0c, 0x50, 0x6f, 0x73, 0x74, 0x75, 0x72, 0x65, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x6f, 0x73, 0x74, 0x75, 0x72, 0x65, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x49, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x6f, - 0x73, 0x74, 0x75, 0x72, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0b, - 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x33, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x65, - 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x73, 0x74, - 0x75, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x32, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x31, 0x0a, - 0x02, 0x6e, 0x61, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x65, 0x64, 0x67, 0x65, - 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x75, 0x72, 0x65, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x4e, 0x6f, 0x6e, 0x65, 0x48, 0x00, 0x52, 0x02, 0x6e, 0x61, - 0x12, 0x3e, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x46, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, - 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x75, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x50, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x1a, 0x06, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x1a, 0x6f, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x12, 0x4e, 0x0a, 0x0d, 0x68, 0x61, 0x73, - 0x68, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x28, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, - 0x50, 0x6f, 0x73, 0x74, 0x75, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x48, 0x61, 0x73, - 0x68, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x52, 0x0d, 0x68, 0x61, 0x73, 0x68, - 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x22, 0x38, 0x0a, 0x04, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x53, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x41, 0x43, - 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x44, 0x4f, - 0x4d, 0x41, 0x49, 0x4e, 0x10, 0x14, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, - 0x53, 0x10, 0x1e, 0x22, 0x1b, 0x0a, 0x0d, 0x48, 0x61, 0x73, 0x68, 0x41, 0x6c, 0x67, 0x6f, 0x72, - 0x69, 0x74, 0x68, 0x6d, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x35, 0x31, 0x32, 0x10, 0x00, - 0x42, 0x0c, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0xa9, - 0x08, 0x0a, 0x0f, 0x50, 0x6f, 0x73, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x3b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x14, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x23, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, - 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, - 0x3e, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x22, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, - 0x50, 0x6f, 0x73, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, - 0x50, 0x72, 0x6f, 0x63, 0x48, 0x00, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, - 0x3e, 0x0a, 0x03, 0x6d, 0x61, 0x63, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x65, - 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x73, 0x74, - 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x61, 0x63, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x48, 0x00, 0x52, 0x03, 0x6d, 0x61, 0x63, 0x12, - 0x45, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2b, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x50, - 0x6f, 0x73, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x57, - 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x48, 0x00, 0x52, 0x06, - 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3f, 0x0a, 0x02, 0x6f, 0x73, 0x18, 0x3c, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, - 0x62, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x73, 0x74, 0x65, - 0x6d, 0x48, 0x00, 0x52, 0x02, 0x6f, 0x73, 0x1a, 0xac, 0x02, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x12, 0x3c, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x28, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x50, - 0x6f, 0x73, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, - 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x41, 0x0a, 0x04, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, - 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x44, 0x61, 0x74, - 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, - 0x44, 0x61, 0x74, 0x61, 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, 0x4f, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x0b, 0x0a, - 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x55, 0x4e, - 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x5f, 0x51, 0x55, 0x45, 0x52, 0x59, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x10, 0x0a, 0x12, 0x1e, 0x0a, 0x1a, 0x55, 0x4e, 0x53, 0x55, 0x50, 0x50, - 0x4f, 0x52, 0x54, 0x45, 0x44, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x41, 0x4c, 0x47, 0x4f, 0x52, - 0x49, 0x54, 0x48, 0x4d, 0x10, 0x14, 0x1a, 0x54, 0x0a, 0x04, 0x50, 0x72, 0x6f, 0x63, 0x12, 0x1e, - 0x0a, 0x0a, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x48, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x48, 0x61, 0x73, 0x68, 0x12, 0x2c, - 0x0a, 0x11, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, - 0x69, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x73, 0x69, 0x67, 0x6e, 0x65, - 0x72, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x1a, 0x2c, 0x0a, 0x0c, - 0x4d, 0x61, 0x63, 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, 0x1a, 0x23, 0x0a, 0x0d, 0x57, 0x69, - 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, - 0xdd, 0x01, 0x0a, 0x0f, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x12, 0x46, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x32, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, - 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x14, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x22, 0x52, 0x0a, 0x04, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x10, 0x00, - 0x12, 0x07, 0x0a, 0x03, 0x69, 0x4f, 0x53, 0x10, 0x0a, 0x12, 0x09, 0x0a, 0x05, 0x4c, 0x69, 0x6e, - 0x75, 0x78, 0x10, 0x14, 0x12, 0x09, 0x0a, 0x05, 0x6d, 0x61, 0x63, 0x4f, 0x53, 0x10, 0x1e, 0x12, - 0x0b, 0x0a, 0x07, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x10, 0x28, 0x12, 0x11, 0x0a, 0x0d, - 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x10, 0x32, 0x42, - 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2a, 0xbf, 0x02, 0x0a, 0x0b, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x65, - 0x72, 0x6f, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x65, - 0x6c, 0x6c, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x10, 0xa0, 0x9c, 0x01, 0x12, 0x15, 0x0a, 0x0f, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x10, 0xa1, - 0x9c, 0x01, 0x12, 0x0f, 0x0a, 0x09, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x10, - 0xa2, 0x9c, 0x01, 0x12, 0x16, 0x0a, 0x10, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x41, 0x64, - 0x64, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x10, 0x84, 0x9d, 0x01, 0x12, 0x18, 0x0a, 0x12, 0x53, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, - 0x65, 0x10, 0x85, 0x9d, 0x01, 0x12, 0x18, 0x0a, 0x12, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x10, 0x86, 0x9d, 0x01, 0x12, - 0x19, 0x0a, 0x13, 0x41, 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, - 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe8, 0x9d, 0x01, 0x12, 0x1b, 0x0a, 0x15, 0x41, 0x70, - 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x54, - 0x79, 0x70, 0x65, 0x10, 0xe9, 0x9d, 0x01, 0x12, 0x1b, 0x0a, 0x15, 0x41, 0x70, 0x69, 0x53, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, - 0x10, 0xea, 0x9d, 0x01, 0x12, 0x1d, 0x0a, 0x17, 0x41, 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, - 0xeb, 0x9d, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x79, 0x70, - 0x65, 0x10, 0xcc, 0x9e, 0x01, 0x12, 0x15, 0x0a, 0x0f, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, - 0x65, 0x72, 0x74, 0x73, 0x54, 0x79, 0x70, 0x65, 0x10, 0xcd, 0x9e, 0x01, 0x2a, 0x21, 0x0a, 0x0b, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x44, - 0x69, 0x61, 0x6c, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x69, 0x6e, 0x64, 0x10, 0x01, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_edge_ctrl_proto_rawDescOnce sync.Once - file_edge_ctrl_proto_rawDescData = file_edge_ctrl_proto_rawDesc -) - -func file_edge_ctrl_proto_rawDescGZIP() []byte { - file_edge_ctrl_proto_rawDescOnce.Do(func() { - file_edge_ctrl_proto_rawDescData = protoimpl.X.CompressGZIP(file_edge_ctrl_proto_rawDescData) - }) - return file_edge_ctrl_proto_rawDescData -} - -var file_edge_ctrl_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_edge_ctrl_proto_msgTypes = make([]protoimpl.MessageInfo, 25) -var file_edge_ctrl_proto_goTypes = []interface{}{ - (ContentType)(0), // 0: edge_ctrl.pb.ContentType - (SessionType)(0), // 1: edge_ctrl.pb.SessionType - (PostureQuery_Type)(0), // 2: edge_ctrl.pb.PostureQuery.Type - (PostureQuery_HashAlgorithm)(0), // 3: edge_ctrl.pb.PostureQuery.HashAlgorithm - (PostureResponse_Error_Code)(0), // 4: edge_ctrl.pb.PostureResponse.Error.Code - (PostureResponse_OperatingSystem_Type)(0), // 5: edge_ctrl.pb.PostureResponse.OperatingSystem.Type - (*ServerHello)(nil), // 6: edge_ctrl.pb.ServerHello - (*ClientHello)(nil), // 7: edge_ctrl.pb.ClientHello - (*Error)(nil), // 8: edge_ctrl.pb.Error - (*Service)(nil), // 9: edge_ctrl.pb.Service - (*Session)(nil), // 10: edge_ctrl.pb.Session - (*ApiSession)(nil), // 11: edge_ctrl.pb.ApiSession - (*ApiSessionAdded)(nil), // 12: edge_ctrl.pb.ApiSessionAdded - (*ApiSessionUpdated)(nil), // 13: edge_ctrl.pb.ApiSessionUpdated - (*ApiSessionRemoved)(nil), // 14: edge_ctrl.pb.ApiSessionRemoved - (*ApiSessionHeartbeat)(nil), // 15: edge_ctrl.pb.ApiSessionHeartbeat - (*SessionAdded)(nil), // 16: edge_ctrl.pb.SessionAdded - (*SessionRemoved)(nil), // 17: edge_ctrl.pb.SessionRemoved - (*SessionUpdated)(nil), // 18: edge_ctrl.pb.SessionUpdated - (*PostureQuery)(nil), // 19: edge_ctrl.pb.PostureQuery - (*PostureResponse)(nil), // 20: edge_ctrl.pb.PostureResponse - nil, // 21: edge_ctrl.pb.ServerHello.DataEntry - nil, // 22: edge_ctrl.pb.ClientHello.DataEntry - (*PostureQuery_None)(nil), // 23: edge_ctrl.pb.PostureQuery.None - (*PostureQuery_Process)(nil), // 24: edge_ctrl.pb.PostureQuery.Process - (*PostureResponse_Error)(nil), // 25: edge_ctrl.pb.PostureResponse.Error - (*PostureResponse_Proc)(nil), // 26: edge_ctrl.pb.PostureResponse.Proc - (*PostureResponse_MacAddresses)(nil), // 27: edge_ctrl.pb.PostureResponse.MacAddresses - (*PostureResponse_WindowsDomain)(nil), // 28: edge_ctrl.pb.PostureResponse.WindowsDomain - (*PostureResponse_OperatingSystem)(nil), // 29: edge_ctrl.pb.PostureResponse.OperatingSystem - nil, // 30: edge_ctrl.pb.PostureResponse.Error.DataEntry -} -var file_edge_ctrl_proto_depIdxs = []int32{ - 21, // 0: edge_ctrl.pb.ServerHello.data:type_name -> edge_ctrl.pb.ServerHello.DataEntry - 22, // 1: edge_ctrl.pb.ClientHello.data:type_name -> edge_ctrl.pb.ClientHello.DataEntry - 1, // 2: edge_ctrl.pb.Session.type:type_name -> edge_ctrl.pb.SessionType - 9, // 3: edge_ctrl.pb.Session.service:type_name -> edge_ctrl.pb.Service - 11, // 4: edge_ctrl.pb.ApiSessionAdded.apiSessions:type_name -> edge_ctrl.pb.ApiSession - 11, // 5: edge_ctrl.pb.ApiSessionUpdated.apiSessions:type_name -> edge_ctrl.pb.ApiSession - 10, // 6: edge_ctrl.pb.SessionAdded.sessions:type_name -> edge_ctrl.pb.Session - 9, // 7: edge_ctrl.pb.SessionUpdated.service:type_name -> edge_ctrl.pb.Service - 2, // 8: edge_ctrl.pb.PostureQuery.type:type_name -> edge_ctrl.pb.PostureQuery.Type - 23, // 9: edge_ctrl.pb.PostureQuery.na:type_name -> edge_ctrl.pb.PostureQuery.None - 24, // 10: edge_ctrl.pb.PostureQuery.process:type_name -> edge_ctrl.pb.PostureQuery.Process - 25, // 11: edge_ctrl.pb.PostureResponse.error:type_name -> edge_ctrl.pb.PostureResponse.Error - 26, // 12: edge_ctrl.pb.PostureResponse.process:type_name -> edge_ctrl.pb.PostureResponse.Proc - 27, // 13: edge_ctrl.pb.PostureResponse.mac:type_name -> edge_ctrl.pb.PostureResponse.MacAddresses - 28, // 14: edge_ctrl.pb.PostureResponse.domain:type_name -> edge_ctrl.pb.PostureResponse.WindowsDomain - 29, // 15: edge_ctrl.pb.PostureResponse.os:type_name -> edge_ctrl.pb.PostureResponse.OperatingSystem - 3, // 16: edge_ctrl.pb.PostureQuery.Process.hashAlgorithm:type_name -> edge_ctrl.pb.PostureQuery.HashAlgorithm - 4, // 17: edge_ctrl.pb.PostureResponse.Error.code:type_name -> edge_ctrl.pb.PostureResponse.Error.Code - 30, // 18: edge_ctrl.pb.PostureResponse.Error.data:type_name -> edge_ctrl.pb.PostureResponse.Error.DataEntry - 5, // 19: edge_ctrl.pb.PostureResponse.OperatingSystem.type:type_name -> edge_ctrl.pb.PostureResponse.OperatingSystem.Type - 20, // [20:20] is the sub-list for method output_type - 20, // [20:20] is the sub-list for method input_type - 20, // [20:20] is the sub-list for extension type_name - 20, // [20:20] is the sub-list for extension extendee - 0, // [0:20] is the sub-list for field type_name -} - -func init() { file_edge_ctrl_proto_init() } -func file_edge_ctrl_proto_init() { - if File_edge_ctrl_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_edge_ctrl_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ServerHello); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ClientHello); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Error); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Service); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Session); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApiSession); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApiSessionAdded); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApiSessionUpdated); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApiSessionRemoved); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApiSessionHeartbeat); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SessionAdded); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SessionRemoved); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SessionUpdated); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PostureQuery); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PostureResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PostureQuery_None); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PostureQuery_Process); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PostureResponse_Error); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PostureResponse_Proc); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PostureResponse_MacAddresses); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PostureResponse_WindowsDomain); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_edge_ctrl_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PostureResponse_OperatingSystem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_edge_ctrl_proto_msgTypes[13].OneofWrappers = []interface{}{ - (*PostureQuery_Na)(nil), - (*PostureQuery_Process_)(nil), - } - file_edge_ctrl_proto_msgTypes[14].OneofWrappers = []interface{}{ - (*PostureResponse_Error_)(nil), - (*PostureResponse_Process)(nil), - (*PostureResponse_Mac)(nil), - (*PostureResponse_Domain)(nil), - (*PostureResponse_Os)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_edge_ctrl_proto_rawDesc, - NumEnums: 6, - NumMessages: 25, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_edge_ctrl_proto_goTypes, - DependencyIndexes: file_edge_ctrl_proto_depIdxs, - EnumInfos: file_edge_ctrl_proto_enumTypes, - MessageInfos: file_edge_ctrl_proto_msgTypes, - }.Build() - File_edge_ctrl_proto = out.File - file_edge_ctrl_proto_rawDesc = nil - file_edge_ctrl_proto_goTypes = nil - file_edge_ctrl_proto_depIdxs = nil +var fileDescriptor_23f46a161f139ee1 = []byte{ + // 781 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0x4d, 0x6f, 0xd3, 0x4a, + 0x14, 0xed, 0x38, 0x49, 0x93, 0xdc, 0xf4, 0x35, 0x7e, 0xf3, 0x9a, 0x3e, 0xb7, 0xef, 0x3d, 0x29, + 0xcf, 0xb0, 0x88, 0x2a, 0x35, 0x88, 0xb2, 0x28, 0xaa, 0xc4, 0xa2, 0xf4, 0x43, 0x45, 0x2c, 0x40, + 0x2e, 0x6c, 0x90, 0x00, 0xb9, 0xf6, 0x55, 0xb1, 0xea, 0x7a, 0xc2, 0xcc, 0x24, 0x52, 0xf6, 0xc0, + 0x7f, 0x40, 0x6a, 0x2a, 0xe0, 0xf7, 0xc0, 0x5f, 0x60, 0xcd, 0xd7, 0x8e, 0x15, 0x3b, 0x34, 0xe3, + 0x8f, 0x38, 0xa9, 0x2b, 0x68, 0x77, 0x73, 0xcf, 0x99, 0x39, 0x9e, 0x73, 0xe6, 0xce, 0x18, 0x9a, + 0xe8, 0x1f, 0xe2, 0x53, 0x4f, 0xf2, 0xb0, 0xdb, 0xe3, 0x4c, 0x32, 0x3a, 0x97, 0x03, 0x0e, 0xec, + 0xd7, 0x04, 0x1a, 0xfb, 0xc8, 0x07, 0xc8, 0xf7, 0x30, 0x0c, 0x19, 0xb5, 0xa0, 0x3a, 0x40, 0x2e, + 0x02, 0x16, 0x59, 0xa4, 0x4d, 0x3a, 0x75, 0x27, 0x2d, 0xe9, 0x3a, 0x94, 0x7d, 0x57, 0xba, 0x96, + 0xd1, 0x2e, 0x75, 0x1a, 0x6b, 0x57, 0xba, 0x79, 0x99, 0x6e, 0x4e, 0xa2, 0xbb, 0xed, 0x4a, 0x77, + 0x27, 0x92, 0x7c, 0xe8, 0xe8, 0x05, 0xcb, 0xeb, 0x50, 0xcf, 0x20, 0x6a, 0x42, 0xe9, 0x08, 0x87, + 0x89, 0xb6, 0x1a, 0xd2, 0x05, 0xa8, 0x0c, 0xdc, 0xb0, 0x8f, 0x96, 0xa1, 0xb1, 0xb8, 0xd8, 0x30, + 0x6e, 0x12, 0xfb, 0x07, 0x81, 0xc6, 0x56, 0x18, 0x60, 0x24, 0x7f, 0xb5, 0xb7, 0x65, 0xa8, 0x3d, + 0x63, 0x42, 0x46, 0xee, 0x71, 0x2a, 0x93, 0xd5, 0xf4, 0x5f, 0xa8, 0x6b, 0xe3, 0x1e, 0x0b, 0x85, + 0x55, 0x6a, 0x97, 0x3a, 0x75, 0x67, 0x0c, 0x64, 0xae, 0xca, 0x45, 0xae, 0x72, 0x1f, 0x9f, 0x76, + 0x45, 0xaf, 0xc2, 0x1f, 0xa9, 0xca, 0x7d, 0xc6, 0xa5, 0xb0, 0x2a, 0x5a, 0x7a, 0x12, 0xbc, 0xbc, + 0xf7, 0xbb, 0x50, 0xd9, 0xe1, 0x9c, 0x71, 0x4a, 0xa1, 0xec, 0x31, 0x1f, 0x93, 0x55, 0x7a, 0xac, + 0x82, 0x38, 0x46, 0x21, 0xdc, 0xc3, 0x74, 0x61, 0x5a, 0x2a, 0x41, 0xcf, 0xed, 0x0b, 0xb4, 0x4a, + 0xb1, 0xa0, 0x2e, 0xec, 0xc7, 0x50, 0x55, 0x07, 0x14, 0x78, 0x48, 0xe7, 0xc1, 0x08, 0xfc, 0x44, + 0xcc, 0x08, 0x7c, 0x25, 0x9f, 0x4b, 0x4d, 0x8f, 0x69, 0x17, 0x28, 0x46, 0x1e, 0x1f, 0xf6, 0x64, + 0xc0, 0x22, 0x07, 0x9f, 0xf7, 0x03, 0x8e, 0xbe, 0x56, 0xac, 0x39, 0x05, 0x8c, 0xfd, 0x9d, 0x28, + 0x7d, 0xa1, 0x4f, 0x62, 0x01, 0x2a, 0x92, 0x1d, 0x61, 0x7a, 0x42, 0x71, 0x41, 0x57, 0xa1, 0x2c, + 0x87, 0xbd, 0xf8, 0x2b, 0xf3, 0x6b, 0x4b, 0xd3, 0xbd, 0xa3, 0x97, 0x3e, 0x18, 0xf6, 0xd0, 0xd1, + 0xd3, 0xe8, 0x0a, 0x98, 0x1e, 0x72, 0xb9, 0x1b, 0x44, 0x87, 0xc8, 0x7b, 0x3c, 0x88, 0x64, 0x7a, + 0x72, 0x67, 0x70, 0x65, 0xa0, 0xcf, 0x43, 0xa1, 0x0f, 0xb0, 0xee, 0xe8, 0x31, 0xbd, 0x06, 0x55, + 0x11, 0xfb, 0xb5, 0x2a, 0x6d, 0xd2, 0x69, 0xac, 0xb5, 0xce, 0x76, 0x6b, 0xe0, 0xa1, 0x93, 0xce, + 0x4a, 0x52, 0xa9, 0x66, 0xa9, 0xd8, 0x30, 0xe7, 0xf6, 0x82, 0x64, 0x63, 0x77, 0x7c, 0xab, 0xa6, + 0x99, 0x09, 0xcc, 0x7e, 0x02, 0xb0, 0x99, 0xd5, 0xe7, 0xf8, 0x2e, 0x32, 0x62, 0x9c, 0x63, 0x24, + 0xde, 0x43, 0x29, 0xdd, 0x83, 0xcd, 0xa0, 0x39, 0xd6, 0xdf, 0xf4, 0x7d, 0xf4, 0x69, 0x1b, 0x1a, + 0x81, 0xd8, 0xed, 0x87, 0xe1, 0xbe, 0x74, 0x65, 0xdc, 0x12, 0x35, 0x27, 0x0f, 0xd1, 0x0d, 0x68, + 0x8c, 0x37, 0x29, 0x92, 0xbb, 0x6a, 0x4d, 0xba, 0x1f, 0xab, 0x3a, 0xf9, 0xc9, 0xf6, 0x3d, 0xf8, + 0x73, 0x4c, 0x3d, 0xec, 0xf9, 0xae, 0x44, 0x7f, 0x5a, 0x90, 0x5c, 0x44, 0xf0, 0x56, 0x5e, 0xd0, + 0xc1, 0x63, 0x36, 0x40, 0x9f, 0x2e, 0xc2, 0xac, 0xce, 0x26, 0xd6, 0xaa, 0x3b, 0x49, 0xa5, 0x2e, + 0x47, 0xe0, 0xa7, 0xe9, 0xa8, 0xa1, 0xbd, 0x0a, 0x7f, 0x8d, 0x97, 0xef, 0xa1, 0xcb, 0xe5, 0x01, + 0xba, 0xf2, 0x3c, 0x01, 0xdb, 0x83, 0xb9, 0x0b, 0x86, 0x75, 0x1d, 0x6a, 0x62, 0x32, 0xa9, 0x56, + 0x61, 0x67, 0x3a, 0xd9, 0x34, 0x7b, 0x03, 0xe6, 0x2f, 0xed, 0xe7, 0x28, 0x5b, 0x9b, 0x86, 0x5b, + 0xdc, 0x34, 0x69, 0x47, 0x1b, 0xc5, 0x1d, 0x5d, 0xfa, 0x9d, 0x8e, 0x56, 0xe1, 0xa9, 0xfb, 0x89, + 0x42, 0xc6, 0x8f, 0x98, 0x83, 0xfb, 0xc3, 0xc8, 0x53, 0xbb, 0xe5, 0xe8, 0x8a, 0xec, 0x05, 0x4d, + 0xaa, 0x95, 0x8f, 0x06, 0x34, 0xb6, 0x58, 0x24, 0x31, 0x92, 0xea, 0x1e, 0xd2, 0x1a, 0x94, 0x1f, + 0x21, 0x67, 0xe6, 0x0c, 0x6d, 0x41, 0x33, 0xf7, 0xb8, 0x2b, 0xd2, 0x7c, 0x73, 0x42, 0x14, 0x9c, + 0x7b, 0x1d, 0x35, 0xfc, 0xf6, 0x84, 0xd0, 0x26, 0xd4, 0xf5, 0xb3, 0xa5, 0x81, 0x77, 0x27, 0x84, + 0x2e, 0x82, 0x99, 0x3f, 0x15, 0x8d, 0xbf, 0x18, 0x11, 0x6a, 0x01, 0x9d, 0x0c, 0x43, 0x33, 0x2f, + 0x27, 0x98, 0x24, 0x62, 0xcd, 0xbc, 0x1a, 0x11, 0xba, 0x94, 0x6f, 0x88, 0xb1, 0xdc, 0xa7, 0x11, + 0xa1, 0xff, 0x40, 0xeb, 0x4c, 0xef, 0x6a, 0xf2, 0xf3, 0x34, 0x99, 0x17, 0xfd, 0x32, 0x22, 0xf4, + 0x3f, 0xf8, 0xbb, 0xa0, 0xcb, 0x34, 0xfd, 0x35, 0xa6, 0x0b, 0x72, 0xd4, 0xf4, 0xb7, 0x11, 0xa1, + 0x26, 0xc0, 0x4e, 0xc4, 0x59, 0x18, 0x6a, 0xe4, 0xfd, 0xa9, 0x0e, 0x26, 0x46, 0xb6, 0x90, 0x4b, + 0xa1, 0xe1, 0x0f, 0xa7, 0x64, 0xe5, 0x7f, 0xf5, 0x9b, 0xcd, 0xde, 0x39, 0x95, 0xef, 0x76, 0xe0, + 0x86, 0xe6, 0x8c, 0x1a, 0xdd, 0x0e, 0x22, 0xdf, 0x24, 0x07, 0xb3, 0xfa, 0xd7, 0x71, 0xe3, 0x67, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x61, 0x6e, 0x18, 0xb2, 0x07, 0x00, 0x00, } diff --git a/pb/edge_ctrl_pb/edge_ctrl.proto b/pb/edge_ctrl_pb/edge_ctrl.proto index 8f25e0e9e..93313537f 100644 --- a/pb/edge_ctrl_pb/edge_ctrl.proto +++ b/pb/edge_ctrl_pb/edge_ctrl.proto @@ -14,6 +14,7 @@ enum ContentType { ApiSessionUpdatedType = 20201; ApiSessionRemovedType = 20202; ApiSessionHeartbeatType = 20203; + RequestClientReSyncType = 20204; EnrollType = 20300; EnrollCertsType = 20301; } @@ -75,6 +76,7 @@ message ApiSessionUpdated { message ApiSessionRemoved { repeated string tokens = 1; + repeated string ids = 2; } message ApiSessionHeartbeat { @@ -88,6 +90,7 @@ message SessionAdded { message SessionRemoved { repeated string tokens = 1; + repeated string ids = 2; } message SessionUpdated { @@ -96,89 +99,6 @@ message SessionUpdated { Service service = 3; } -message PostureQuery { - string id = 1; - string postureCheckId = 20; - string displayName = 30; - PostureQuery.Type type = 40; - string version = 50; - oneof parameters { - PostureQuery.None na = 60; - PostureQuery.Process process = 70; - - } - - enum Type { - OS = 0; - MAC = 10; - WINDOWS_DOMAIN = 20; - PROCESS = 30; - } - - enum HashAlgorithm { - SHA512 = 0; - } - - message None { - - } - - message Process { - repeated string paths = 1; - HashAlgorithm hashAlgorithm = 10; - } +message RequestClientReSync { + string reason = 1; } - - -message PostureResponse { - string id = 1; - oneof payload { - PostureResponse.Error error = 20; - PostureResponse.Proc process = 30; - PostureResponse.MacAddresses mac = 40; - PostureResponse.WindowsDomain domain = 50; - PostureResponse.OperatingSystem os = 60; - } - - - message Error { - enum Code { - UNKNOWN = 0; - UNSUPPORTED_QUERY_TYPE = 10; - UNSUPPORTED_HASH_ALGORITHM = 20; - } - - PostureResponse.Error.Code code = 1; - string message = 10; - map data = 20; - } - - message Proc { - string binaryHash = 1; - string signerFingerprint = 10; - } - - message MacAddresses { - repeated string addresses = 1; - } - - message WindowsDomain { - string name = 1; - } - - message OperatingSystem { - PostureResponse.OperatingSystem.Type type = 1; - string version = 10; - string build = 20; - - enum Type { - Android = 0; - iOS = 10; - Linux = 20; - macOS = 30; - Windows = 40; - WindowsServer = 50; - } - } -} - diff --git a/rest_model/edge_router_detail.go b/rest_model/edge_router_detail.go index 1d342b476..2b9c65ecb 100644 --- a/rest_model/edge_router_detail.go +++ b/rest_model/edge_router_detail.go @@ -83,6 +83,10 @@ type EdgeRouterDetail struct { // Required: true SupportedProtocols map[string]string `json:"supportedProtocols"` + // sync status + // Required: true + SyncStatus *string `json:"syncStatus"` + // version info VersionInfo *VersionInfo `json:"versionInfo,omitempty"` } @@ -120,6 +124,8 @@ func (m *EdgeRouterDetail) UnmarshalJSON(raw []byte) error { SupportedProtocols map[string]string `json:"supportedProtocols"` + SyncStatus *string `json:"syncStatus"` + VersionInfo *VersionInfo `json:"versionInfo,omitempty"` } if err := swag.ReadJSON(raw, &dataAO1); err != nil { @@ -148,6 +154,8 @@ func (m *EdgeRouterDetail) UnmarshalJSON(raw []byte) error { m.SupportedProtocols = dataAO1.SupportedProtocols + m.SyncStatus = dataAO1.SyncStatus + m.VersionInfo = dataAO1.VersionInfo return nil @@ -185,6 +193,8 @@ func (m EdgeRouterDetail) MarshalJSON() ([]byte, error) { SupportedProtocols map[string]string `json:"supportedProtocols"` + SyncStatus *string `json:"syncStatus"` + VersionInfo *VersionInfo `json:"versionInfo,omitempty"` } @@ -210,6 +220,8 @@ func (m EdgeRouterDetail) MarshalJSON() ([]byte, error) { dataAO1.SupportedProtocols = m.SupportedProtocols + dataAO1.SyncStatus = m.SyncStatus + dataAO1.VersionInfo = m.VersionInfo jsonDataAO1, errAO1 := swag.WriteJSON(dataAO1) @@ -261,6 +273,10 @@ func (m *EdgeRouterDetail) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateSyncStatus(formats); err != nil { + res = append(res, err) + } + if err := m.validateVersionInfo(formats); err != nil { res = append(res, err) } @@ -354,6 +370,15 @@ func (m *EdgeRouterDetail) validateSupportedProtocols(formats strfmt.Registry) e return nil } +func (m *EdgeRouterDetail) validateSyncStatus(formats strfmt.Registry) error { + + if err := validate.Required("syncStatus", "body", m.SyncStatus); err != nil { + return err + } + + return nil +} + func (m *EdgeRouterDetail) validateVersionInfo(formats strfmt.Registry) error { if swag.IsZero(m.VersionInfo) { // not required diff --git a/rest_server/embedded_spec.go b/rest_server/embedded_spec.go index f4f76ed4c..9c0978dc8 100644 --- a/rest_server/embedded_spec.go +++ b/rest_server/embedded_spec.go @@ -7645,7 +7645,8 @@ func init() { "version", "arch", "buildDate", - "revision" + "revision", + "syncStatus" ], "properties": { "enrollmentCreatedAt": { @@ -7690,6 +7691,9 @@ func init() { "type": "string" } }, + "syncStatus": { + "type": "string" + }, "versionInfo": { "$ref": "#/definitions/versionInfo" } @@ -27181,7 +27185,8 @@ func init() { "version", "arch", "buildDate", - "revision" + "revision", + "syncStatus" ], "properties": { "enrollmentCreatedAt": { @@ -27226,6 +27231,9 @@ func init() { "type": "string" } }, + "syncStatus": { + "type": "string" + }, "versionInfo": { "$ref": "#/definitions/versionInfo" } diff --git a/router/handler_edge_ctrl/apiSessionAdded.go b/router/handler_edge_ctrl/apiSessionAdded.go index 19ce02679..6660fa03e 100644 --- a/router/handler_edge_ctrl/apiSessionAdded.go +++ b/router/handler_edge_ctrl/apiSessionAdded.go @@ -17,21 +17,57 @@ package handler_edge_ctrl import ( + "encoding/json" + "errors" + "fmt" "github.com/golang/protobuf/proto" "github.com/michaelquigley/pfxlog" "github.com/openziti/edge/controller/env" - "github.com/openziti/edge/router/internal/fabric" + "github.com/openziti/edge/controller/sync_strats" "github.com/openziti/edge/pb/edge_ctrl_pb" + "github.com/openziti/edge/router/internal/fabric" "github.com/openziti/foundation/channel2" + "sync" + "time" ) type apiSessionAddedHandler struct { - sm fabric.StateManager + control channel2.Channel + sm fabric.StateManager + syncTracker *apiSessionSyncTracker + + reqChan chan *apiSessionAddedWithState + syncReady chan []*edge_ctrl_pb.ApiSession + syncFail chan error + + stop chan struct{} } -func NewApiSessionAddedHandler(sm fabric.StateManager) *apiSessionAddedHandler { - return &apiSessionAddedHandler{ - sm: sm, +func NewApiSessionAddedHandler(sm fabric.StateManager, control channel2.Channel) *apiSessionAddedHandler { + handler := &apiSessionAddedHandler{ + control: control, + sm: sm, + reqChan: make(chan *apiSessionAddedWithState, 100), + + syncReady: make(chan []*edge_ctrl_pb.ApiSession, 0), + syncFail: make(chan error, 0), + + stop: make(chan struct{}, 0), + } + + go handler.startReceiveSync() + go handler.startSyncApplier() + go handler.startSyncFail() + + control.AddCloseHandler(handler) + + return handler +} + +func (h *apiSessionAddedHandler) HandleClose(_ channel2.Channel) { + if h.stop != nil { + close(h.stop) + h.stop = nil } } @@ -39,19 +75,256 @@ func (h *apiSessionAddedHandler) ContentType() int32 { return env.ApiSessionAddedType } -func (h *apiSessionAddedHandler) HandleReceive(msg *channel2.Message, ch channel2.Channel) { +func (h *apiSessionAddedHandler) HandleReceive(msg *channel2.Message, _ channel2.Channel) { go func() { req := &edge_ctrl_pb.ApiSessionAdded{} if err := proto.Unmarshal(msg.Body, req); err == nil { - for _, session := range req.ApiSessions { - h.sm.AddApiSession(session) - } - if req.IsFullState { - h.sm.RemoveMissingApiSessions(req.ApiSessions) + + reqWithState := &apiSessionAddedWithState{ + ApiSessionAdded: req, + } + + if syncStrategyType, syncState, err := parseInstantSyncHeaders(msg); err == nil { + reqWithState.SyncStrategyType = syncStrategyType + reqWithState.InstantSyncState = syncState + } else { + pfxlog.Logger().WithField("msgContentType", msg.ContentType).WithError(err).Errorf("sync headers not present (old controller) or only partial present(error), treating as legacy: %v", err) + } + + h.reqChan <- reqWithState + } else { + for _, session := range req.ApiSessions { + h.sm.AddApiSession(session) + } } } else { - pfxlog.Logger().Panic("could not convert message as network session added") + pfxlog.Logger().Panic("could not convert message as api session added") } }() } + +func (h *apiSessionAddedHandler) startSyncApplier() { + for { + select { + case <-h.stop: + return + case apiSessions := <-h.syncReady: + for _, apiSession := range apiSessions { + h.sm.AddApiSession(apiSession) + } + h.sm.RemoveMissingApiSessions(apiSessions) + + pfxlog.Logger().Infof("finished sychronizing api sessions [count: %d]", len(apiSessions)) + } + } +} + +func (h *apiSessionAddedHandler) startSyncFail() { + for { + select { + case <-h.stop: + return + case err := <-h.syncFail: + pfxlog.Logger().Errorf("failed to synchronize api sessions: %v", err) + + h.syncTracker.Stop() + h.syncTracker = nil + + resync := &edge_ctrl_pb.RequestClientReSync{ + Reason: fmt.Sprintf("error during api session sync: %v", err), + } + + resyncProto, _ := proto.Marshal(resync) + + resyncMsg := channel2.NewMessage(env.RequestClientReSyncType, resyncProto) + _ = h.control.Send(resyncMsg) + } + } +} + +func (h *apiSessionAddedHandler) legacySync(reqWithState *apiSessionAddedWithState) { + pfxlog.Logger().Warn("using legacy sync logic some connections may be dropped") + for _, apiSession := range reqWithState.ApiSessions { + h.sm.AddApiSession(apiSession) + } + + h.sm.RemoveMissingApiSessions(reqWithState.ApiSessions) +} + +func (h *apiSessionAddedHandler) startReceiveSync() { + for { + select { + case <-h.stop: + return + case reqWithState := <-h.reqChan: + switch reqWithState.SyncStrategyType { + case string(sync_strats.RouterSyncStrategyInstant): + h.instantSync(reqWithState) + case "": + pfxlog.Logger().Warn("syncStrategy is not specified, old controller?") + h.legacySync(reqWithState) + default: + pfxlog.Logger().Warnf("syncStrategy [%s] is not supported", reqWithState.SyncStrategyType) + h.legacySync(reqWithState) + } + } + } +} + +func (h *apiSessionAddedHandler) instantSync(reqWithState *apiSessionAddedWithState) { + logger := pfxlog.Logger().WithField("strategy", reqWithState.SyncStrategyType) + + if reqWithState.InstantSyncState == nil { + logger.Panic("syncState is empty, cannot continue") + } + + if reqWithState.InstantSyncState.Id == "" { + logger.Panic("syncState id is empty, cannot continue") + } + + //if no id or the sync id is newer, reset + if h.syncTracker == nil || h.syncTracker.syncId == "" || h.syncTracker.isDone || h.syncTracker.syncId < reqWithState.Id { + + if h.syncTracker == nil || h.syncTracker.syncId == "" { + logger.Infof("first api session syncId [%s], starting", reqWithState.Id) + } else if h.syncTracker.isDone{ + logger.Infof("api session syncId [%s], starting", reqWithState.Id) + } else { + logger.Infof("api session with newer syncId [old: %s, new: %s], aborting old, starting new", h.syncTracker.syncId, reqWithState.Id) + } + + if h.syncTracker != nil { + h.syncTracker.Stop() + } + + h.syncTracker = newApiSessionSyncTracker(reqWithState.Id) + + h.syncTracker.StartDeadline(h.syncReady, h.syncFail, 20*time.Second) + } + + //ignore older syncs + if h.syncTracker.syncId > reqWithState.Id { + logger.Warnf("older syncId [%s], ignoring", reqWithState.Id) + return + } + + h.syncTracker.Add(reqWithState) + +} + +type apiSessionSyncTracker struct { + syncId string + reqsWithState map[int]*apiSessionAddedWithState + hasLast bool + lastSeq int + stop chan struct{} + deadline sync.Once + isDone bool +} + +func newApiSessionSyncTracker(id string) *apiSessionSyncTracker { + return &apiSessionSyncTracker{ + syncId: id, + reqsWithState: map[int]*apiSessionAddedWithState{}, + stop: make(chan struct{}, 0), + } +} + +func (tracker *apiSessionSyncTracker) Add(reqWithState *apiSessionAddedWithState) { + tracker.reqsWithState[reqWithState.Sequence] = reqWithState + + if reqWithState.IsLast { + tracker.hasLast = true + tracker.lastSeq = reqWithState.Sequence + } +} + +func (tracker *apiSessionSyncTracker) Stop() { + if tracker != nil && tracker.stop != nil { + close(tracker.stop) + tracker.stop = nil + } +} + +func (tracker *apiSessionSyncTracker) IsDone() bool { + return tracker.isDone +} + +func (tracker *apiSessionSyncTracker) StartDeadline(syncReady chan []*edge_ctrl_pb.ApiSession, syncFail chan error, timeout time.Duration) { + tracker.deadline.Do(func() { + go func() { + ticker := time.NewTicker(1 * time.Second) + select { + case <-tracker.stop: + tracker.reqsWithState = nil + return + case <-ticker.C: + if tracker.HasAll() { + syncReady <- tracker.all() + tracker.isDone = true + return + } + case <-time.After(timeout): + tracker.reqsWithState = nil + syncFail <- errors.New("timeout, did not receive all updates in time") + return + } + }() + }) +} + +func (tracker *apiSessionSyncTracker) HasAll() bool { + if !tracker.hasLast { + return false + } + + hasAll := true + + for i := 0; i <= tracker.lastSeq; i++ { + if req, ok := tracker.reqsWithState[i]; !ok && req == nil { + hasAll = false + break + } + } + + return hasAll +} + +func (tracker *apiSessionSyncTracker) all() []*edge_ctrl_pb.ApiSession { + var result []*edge_ctrl_pb.ApiSession + for i := 0; i <= tracker.lastSeq; i++ { + if req, ok := tracker.reqsWithState[i]; ok { + for _, apiSession := range req.ApiSessions { + result = append(result, apiSession) + } + } else { + pfxlog.Logger().WithField("strategy", sync_strats.RouterSyncStrategyInstant).Error("all failed to have all update sequences") + } + } + + return result +} + +type apiSessionAddedWithState struct { + SyncStrategyType string + *sync_strats.InstantSyncState + *edge_ctrl_pb.ApiSessionAdded +} + +func parseInstantSyncHeaders(msg *channel2.Message) (string, *sync_strats.InstantSyncState, error) { + if syncStrategyType, ok := msg.Headers[env.SyncStrategyTypeHeader]; ok { + if syncStrategyState, ok := msg.Headers[env.SyncStrategyStateHeader]; ok { + state := &sync_strats.InstantSyncState{} + if err := json.Unmarshal(syncStrategyState, state); err == nil { + return string(syncStrategyType), state, nil + } else { + pfxlog.Logger().WithField("strategy", syncStrategyType).WithField("msgContentType", msg.ContentType).Panicf("could not parse sync state [%s], error: %v", syncStrategyState, err) + } + + } else { + return "", nil, errors.New("received sync message with a strategy type header, but no state") + } + } + return "", nil, errors.New("received sync message with no strategy type header") +} diff --git a/router/handler_edge_ctrl/apiSessionRemoved.go b/router/handler_edge_ctrl/apiSessionRemoved.go index a16aade5e..bd582aa1b 100644 --- a/router/handler_edge_ctrl/apiSessionRemoved.go +++ b/router/handler_edge_ctrl/apiSessionRemoved.go @@ -20,8 +20,8 @@ import ( "github.com/golang/protobuf/proto" "github.com/michaelquigley/pfxlog" "github.com/openziti/edge/controller/env" - "github.com/openziti/edge/router/internal/fabric" "github.com/openziti/edge/pb/edge_ctrl_pb" + "github.com/openziti/edge/router/internal/fabric" "github.com/openziti/foundation/channel2" ) @@ -43,8 +43,22 @@ func (h *apiSessionRemovedHandler) HandleReceive(msg *channel2.Message, ch chann go func() { req := &edge_ctrl_pb.ApiSessionRemoved{} if err := proto.Unmarshal(msg.Body, req); err == nil { - for _, t := range req.Tokens { - h.sm.RemoveApiSession(t) + + //older controllers will not provide req.Ids + hasIds := len(req.Ids) == len(req.Tokens) + + for i, token := range req.Tokens { + id := "unknown" + if hasIds { + id = req.Ids[i] + } + + pfxlog.Logger(). + WithField("apiSessionToken", token). + WithField("apiSessionId", id). + Debugf("removing api session [token: %s] [id: %s]", token, id) + + h.sm.RemoveApiSession(token) } } else { pfxlog.Logger().Panic("could not convert message as session removed") diff --git a/router/handler_edge_ctrl/sessionAdded.go b/router/handler_edge_ctrl/sessionAdded.go index bc4d55b55..c7f43db73 100644 --- a/router/handler_edge_ctrl/sessionAdded.go +++ b/router/handler_edge_ctrl/sessionAdded.go @@ -17,42 +17,279 @@ package handler_edge_ctrl import ( + "errors" "github.com/golang/protobuf/proto" "github.com/michaelquigley/pfxlog" "github.com/openziti/edge/controller/env" - "github.com/openziti/edge/router/internal/fabric" + "github.com/openziti/edge/controller/sync_strats" "github.com/openziti/edge/pb/edge_ctrl_pb" + "github.com/openziti/edge/router/internal/fabric" "github.com/openziti/foundation/channel2" + "sync" + "time" ) type sessionAddedHandler struct { - sm fabric.StateManager + sm fabric.StateManager + syncTracker *sessionSyncTracker + reqChan chan *sessionAddedWithState + syncReady chan []*edge_ctrl_pb.Session + syncFail chan error + + stop chan struct{} } -func NewSessionAddedHandler(sm fabric.StateManager) *sessionAddedHandler { - return &sessionAddedHandler{ - sm: sm, +func NewSessionAddedHandler(sm fabric.StateManager, control channel2.Channel) *sessionAddedHandler { + handler := &sessionAddedHandler{ + sm: sm, + reqChan: make(chan *sessionAddedWithState, 100), + syncReady: make(chan []*edge_ctrl_pb.Session, 0), + syncFail: make(chan error, 0), + stop: make(chan struct{}), } + + go handler.startReceiveSync() + go handler.startSyncApplier() + go handler.startSyncFail() + + control.AddCloseHandler(handler) + + return handler } func (h *sessionAddedHandler) ContentType() int32 { return env.SessionAddedType } +func (h *sessionAddedHandler) HandleClose(_ channel2.Channel) { + if h.stop != nil { + close(h.stop) + h.stop = nil + } +} + func (h *sessionAddedHandler) HandleReceive(msg *channel2.Message, _ channel2.Channel) { go func() { req := &edge_ctrl_pb.SessionAdded{} if err := proto.Unmarshal(msg.Body, req); err == nil { - for _, session := range req.Sessions { - pfxlog.Logger().Debugf("received new session %+v", session) - h.sm.AddSession(session) - } - if req.IsFullState { - h.sm.RemoveMissingSessions(req.Sessions) + + reqWithState := &sessionAddedWithState{ + SessionAdded: req, + } + + if syncStrategyType, syncState, err := parseInstantSyncHeaders(msg); err == nil { + reqWithState.SyncStrategyType = syncStrategyType + reqWithState.InstantSyncState = syncState + } else { + pfxlog.Logger().WithField("strategy", syncStrategyType).WithField("msgContentType", msg.ContentType).WithError(err).Errorf("sync headers not present (old controller) or only partial present(error), treading as legacy: %v", err) + } + + h.reqChan <- reqWithState + } else { + for _, session := range req.Sessions { + h.sm.AddSession(session) + } } } else { - pfxlog.Logger().Panic("could not convert message as network session added") + pfxlog.Logger().Panic("could not convert message as session added") } }() } + +func (h *sessionAddedHandler) startSyncApplier() { + for { + select { + case <-h.stop: + return + case sessions := <-h.syncReady: + for _, session := range sessions { + h.sm.AddSession(session) + } + h.sm.RemoveMissingSessions(sessions) + + pfxlog.Logger().Infof("finished sychronizing sessions [count: %d]", len(sessions)) + } + } +} + +func (h *sessionAddedHandler) startSyncFail() { + for { + select { + case <-h.stop: + return + case err := <-h.syncFail: + pfxlog.Logger().Errorf("failed to synchronize sessions, aborting: %v", err) + h.syncTracker.Stop() + } + } +} + +func (h *sessionAddedHandler) legacySync(reqWithState *sessionAddedWithState) { + pfxlog.Logger().Warn("using legacy sync logic some connections may be dropped") + for _, session := range reqWithState.Sessions { + h.sm.AddSession(session) + } + + h.sm.RemoveMissingSessions(reqWithState.Sessions) +} + +func (h *sessionAddedHandler) startReceiveSync() { + for { + select { + case <-h.stop: + return + case reqWithState := <-h.reqChan: + switch reqWithState.SyncStrategyType { + case string(sync_strats.RouterSyncStrategyInstant): + h.instantSync(reqWithState) + case "": + pfxlog.Logger().Warn("syncStrategy is not specified, old controller?") + h.legacySync(reqWithState) + default: + pfxlog.Logger().Warnf("syncStrategy [%s] is not supported", reqWithState.SyncStrategyType) + h.legacySync(reqWithState) + } + } + } +} + +func (h *sessionAddedHandler) instantSync(reqWithState *sessionAddedWithState) { + logger := pfxlog.Logger().WithField("strategy", reqWithState.SyncStrategyType) + + if reqWithState.InstantSyncState == nil { + logger.Panic("syncState is empty, cannot continue") + } + + if reqWithState.InstantSyncState.Id == "" { + logger.Panic("syncState id is empty, cannot continue") + } + + //if no id or the sync id is newer, reset + if h.syncTracker == nil || h.syncTracker.syncId == "" || h.syncTracker.IsDone() || h.syncTracker.syncId < reqWithState.Id { + + if h.syncTracker == nil || h.syncTracker.syncId == "" { + logger.Infof("first session syncId [%s], starting", reqWithState.Id) + } else if h.syncTracker.isDone{ + logger.Infof("session syncId [%s], starting", reqWithState.Id) + } else { + logger.Infof("session with newer syncId [old: %s, new: %s], aborting old, starting new", h.syncTracker.syncId, reqWithState.Id) + } + + if h.syncTracker != nil { + h.syncTracker.Stop() + } + + h.syncTracker = newSessionSyncTracker(reqWithState.Id) + + h.syncTracker.StartDeadline(h.syncReady, h.syncFail, 20*time.Second) + } + + //ignore older syncs + if h.syncTracker.syncId > reqWithState.Id { + logger.Warnf("older syncId [%s], ignoring", reqWithState.Id) + return + } + + h.syncTracker.Add(reqWithState) + +} + +type sessionSyncTracker struct { + syncId string + reqsWithState map[int]*sessionAddedWithState + hasLast bool + lastSeq int + stop chan struct{} + deadline sync.Once + isDone bool +} + +func newSessionSyncTracker(id string) *sessionSyncTracker { + return &sessionSyncTracker{ + syncId: id, + reqsWithState: map[int]*sessionAddedWithState{}, + stop: make(chan struct{}, 0), + } +} + +func (tracker *sessionSyncTracker) Add(reqWithState *sessionAddedWithState) { + tracker.reqsWithState[reqWithState.Sequence] = reqWithState + + if reqWithState.IsLast { + tracker.hasLast = true + tracker.lastSeq = reqWithState.Sequence + } +} + +func (tracker *sessionSyncTracker) Stop() { + if tracker != nil && tracker.stop != nil { + close(tracker.stop) + tracker.stop = nil + } +} + +func (tracker *sessionSyncTracker) IsDone() bool { + return tracker.isDone +} + +func (tracker *sessionSyncTracker) StartDeadline(syncReady chan []*edge_ctrl_pb.Session, syncFail chan error, timeout time.Duration) { + tracker.deadline.Do(func() { + go func() { + ticker := time.NewTicker(1 * time.Second) + select { + case <-tracker.stop: + tracker.reqsWithState = nil + return + case <-ticker.C: + if tracker.HasAll() { + syncReady <- tracker.all() + tracker.isDone = true + return + } + case <-time.After(timeout): + tracker.reqsWithState = nil + syncFail <- errors.New("timeout, did not receive all updates in time") + return + } + }() + }) +} + +func (tracker *sessionSyncTracker) HasAll() bool { + if !tracker.hasLast { + return false + } + + hasAll := true + + for i := 0; i <= tracker.lastSeq; i++ { + if req, ok := tracker.reqsWithState[i]; !ok && req == nil { + hasAll = false + break + } + } + + return hasAll +} + +func (tracker *sessionSyncTracker) all() []*edge_ctrl_pb.Session { + var result []*edge_ctrl_pb.Session + for i := 0; i <= tracker.lastSeq; i++ { + if req, ok := tracker.reqsWithState[i]; ok { + for _, session := range req.Sessions { + result = append(result, session) + } + } else { + pfxlog.Logger().WithField("strategy", sync_strats.RouterSyncStrategyInstant).Error("all failed to have all update sequences") + } + } + + return result +} + +type sessionAddedWithState struct { + SyncStrategyType string + *sync_strats.InstantSyncState + *edge_ctrl_pb.SessionAdded +} diff --git a/router/handler_edge_ctrl/sessionRemoved.go b/router/handler_edge_ctrl/sessionRemoved.go index 9d502bda5..571599ba6 100644 --- a/router/handler_edge_ctrl/sessionRemoved.go +++ b/router/handler_edge_ctrl/sessionRemoved.go @@ -20,8 +20,8 @@ import ( "github.com/golang/protobuf/proto" "github.com/michaelquigley/pfxlog" "github.com/openziti/edge/controller/env" - "github.com/openziti/edge/router/internal/fabric" "github.com/openziti/edge/pb/edge_ctrl_pb" + "github.com/openziti/edge/router/internal/fabric" "github.com/openziti/foundation/channel2" ) @@ -43,8 +43,18 @@ func (h *sessionRemovedHandler) HandleReceive(msg *channel2.Message, ch channel2 go func() { req := &edge_ctrl_pb.SessionRemoved{} if err := proto.Unmarshal(msg.Body, req); err == nil { - for _, t := range req.Tokens { - h.sm.RemoveSession(t) + hasIds := len(req.Ids) == len(req.Tokens) + + for i, token := range req.Tokens { + id := "unknown" + if hasIds { + id = req.Ids[i] + } + pfxlog.Logger(). + WithField("sessionToken", token). + WithField("sessionId", id). + Debugf("removing api session [token: %s] [id: %s]", token, id) + h.sm.RemoveSession(token) } } else { pfxlog.Logger().Panic("could not convert message as network session removed") diff --git a/router/internal/fabric/manager.go b/router/internal/fabric/manager.go index c0ddc453a..857562763 100644 --- a/router/internal/fabric/manager.go +++ b/router/internal/fabric/manager.go @@ -55,8 +55,8 @@ type StateManager interface { //ApiSessions GetApiSession(token string) *edge_ctrl_pb.ApiSession GetApiSessionWithTimeout(token string, timeout time.Duration) *edge_ctrl_pb.ApiSession - AddApiSession(ns *edge_ctrl_pb.ApiSession) - UpdateApiSession(ns *edge_ctrl_pb.ApiSession) + AddApiSession(apiSession *edge_ctrl_pb.ApiSession) + UpdateApiSession(apiSession *edge_ctrl_pb.ApiSession) RemoveApiSession(token string) RemoveMissingApiSessions(knownSessions []*edge_ctrl_pb.ApiSession) AddConnectedApiSession(token string, removeCB func(), ch channel2.Channel) @@ -97,20 +97,28 @@ func GetStateManager() StateManager { return singleStateManager } -func (sm *StateManagerImpl) AddApiSession(session *edge_ctrl_pb.ApiSession) { - pfxlog.Logger().Debugf("adding session [%s] fingerprints [%s]", session.Token, session.CertFingerprints) - sm.apiSessionsByToken.Store(session.Token, session) - sm.Emit(EventAddedSession, session) +func (sm *StateManagerImpl) AddApiSession(apiSession *edge_ctrl_pb.ApiSession) { + pfxlog.Logger(). + WithField("apiSessionId", apiSession.Id). + WithField("apiSessionToken", apiSession.Token). + WithField("apiSessionCertFingerprints", apiSession.CertFingerprints). + Debugf("adding apiSession [id: %s] [token: %s] fingerprints [%s]", apiSession.Id, apiSession.Token, apiSession.CertFingerprints) + sm.apiSessionsByToken.Store(apiSession.Token, apiSession) + sm.Emit(EventAddedSession, apiSession) } -func (sm *StateManagerImpl) UpdateApiSession(session *edge_ctrl_pb.ApiSession) { - pfxlog.Logger().Debugf("updating session [%s] fingerprints [%s]", session.Token, session.CertFingerprints) - sm.apiSessionsByToken.Store(session.Token, session) +func (sm *StateManagerImpl) UpdateApiSession(apiSession *edge_ctrl_pb.ApiSession) { + pfxlog.Logger(). + WithField("apiSessionId", apiSession.Id). + WithField("apiSessionToken", apiSession.Token). + WithField("apiSessionCertFingerprints", apiSession.CertFingerprints). + Debugf("updating apiSession [id: %s] [token: %s] fingerprints [%s]", apiSession.Id, apiSession.Token, apiSession.CertFingerprints) + sm.apiSessionsByToken.Store(apiSession.Token, apiSession) sm.sessionsByToken.Range(func(key, value interface{}) bool { if ns, ok := value.(*edge_ctrl_pb.Session); ok { - if ns.ApiSessionId == session.Id { //only update the specific api session's sessions - ns.CertFingerprints = session.CertFingerprints //session.CertFingerprints is all currently valid + if ns.ApiSessionId == apiSession.Id { //only update the specific api apiSession's sessions + ns.CertFingerprints = apiSession.CertFingerprints //apiSession.CertFingerprints is all currently valid } } else { pfxlog.Logger().Warn("could not convert value from concurrent map sessionsByToken to Session, this should not happen") @@ -118,19 +126,19 @@ func (sm *StateManagerImpl) UpdateApiSession(session *edge_ctrl_pb.ApiSession) { return true }) - sm.Emit(EventUpdatedSession, session) + sm.Emit(EventUpdatedSession, apiSession) } func (sm *StateManagerImpl) RemoveApiSession(token string) { if ns, ok := sm.apiSessionsByToken.Load(token); ok { - pfxlog.Logger().Debugf("removing session [%s]", token) + pfxlog.Logger().WithField("apiSessionToken", token).Debugf("removing api session [token: %s]", token) sm.apiSessionsByToken.Delete(token) eventName := sm.getSessionRemovedEventName(token) sm.Emit(eventName) sm.RemoveAllListeners(eventName) sm.Emit(EventRemovedSession, ns) } else { - pfxlog.Logger().Debugf("could not remove session [%s]; not found", token) + pfxlog.Logger().WithField("apiSessionToken", token).Debugf("could not remove api session [token: %s]; not found", token) } } func (sm *StateManagerImpl) RemoveMissingApiSessions(knownSessions []*edge_ctrl_pb.ApiSession) { @@ -153,28 +161,42 @@ func (sm *StateManagerImpl) RemoveMissingApiSessions(knownSessions []*edge_ctrl_ } } -func (sm *StateManagerImpl) AddSession(ns *edge_ctrl_pb.Session) { +func (sm *StateManagerImpl) AddSession(session *edge_ctrl_pb.Session) { // BACKWARDS_COMPATIBILITY introduced 0.15.2 // support 0.14 (and older) style controller generated fingerprints, as fingerprint format changed from 0.14 to 0.15 - for i := 0; i < len(ns.CertFingerprints); i++ { - ns.CertFingerprints[i] = strings.Replace(strings.ToLower(ns.CertFingerprints[i]), ":", "", -1) + for i := 0; i < len(session.CertFingerprints); i++ { + session.CertFingerprints[i] = strings.Replace(strings.ToLower(session.CertFingerprints[i]), ":", "", -1) } - pfxlog.Logger().Debugf("adding network session [%s] fingerprints [%s] TypeId [%v]", ns.Token, ns.CertFingerprints, ns.Type.String()) - sm.sessionsByToken.Store(ns.Token, ns) - sm.Emit(EventAddedNetworkSession, ns) + pfxlog.Logger(). + WithField("apiSessionId", session.ApiSessionId). + WithField("sessionId", session.Id). + WithField("sessionToken", session.Token). + WithField("serviceId", session.Service.Id). + WithField("serviceName", session.Service.Name). + WithField("serviceEncryptionRequired", session.Service.EncryptionRequired). + Debugf("adding session [token: %s] [id: %s] fingerprints [%s] TypeId [%v]", session.Token, session.Id, session.CertFingerprints, session.Type.String()) + sm.sessionsByToken.Store(session.Token, session) + sm.Emit(EventAddedNetworkSession, session) } -func (sm *StateManagerImpl) UpdateSession(ns *edge_ctrl_pb.Session) { +func (sm *StateManagerImpl) UpdateSession(session *edge_ctrl_pb.Session) { // BACKWARDS_COMPATIBILITY introduced 0.15.2 // support 0.14 (and older) style controller generated fingerprints, as fingerprint format changed from 0.14 to 0.15 - for i := 0; i < len(ns.CertFingerprints); i++ { - ns.CertFingerprints[i] = strings.Replace(strings.ToLower(ns.CertFingerprints[i]), ":", "", -1) + for i := 0; i < len(session.CertFingerprints); i++ { + session.CertFingerprints[i] = strings.Replace(strings.ToLower(session.CertFingerprints[i]), ":", "", -1) } - pfxlog.Logger().Debugf("updating network session [%s] fingerprints [%s]", ns.Token, ns.CertFingerprints) - sm.sessionsByToken.Store(ns.Token, ns) - sm.Emit(EventUpdatedNetworkSession, ns) + pfxlog.Logger(). + WithField("apiSessionId", session.ApiSessionId). + WithField("sessionId", session.Id). + WithField("sessionToken", session.Token). + WithField("serviceId", session.Service.Id). + WithField("serviceName", session.Service.Name). + WithField("serviceEncryptionRequired", session.Service.EncryptionRequired). + Debugf("updating session [token: %s] [id: %s] fingerprints [%s]", session.Token, session.Id, session.CertFingerprints) + sm.sessionsByToken.Store(session.Token, session) + sm.Emit(EventUpdatedNetworkSession, session) } func (sm *StateManagerImpl) RemoveMissingSessions(knownSessions []*edge_ctrl_pb.Session) { @@ -199,14 +221,14 @@ func (sm *StateManagerImpl) RemoveMissingSessions(knownSessions []*edge_ctrl_pb. func (sm *StateManagerImpl) RemoveSession(token string) { if ns, ok := sm.sessionsByToken.Load(token); ok { - pfxlog.Logger().Debugf("removing network session [%s]", token) + pfxlog.Logger().Debugf("removing session [token: %s]", token) sm.sessionsByToken.Delete(token) sm.Emit(EventRemovedNetworkSession, ns) eventName := sm.getNetworkSessionRemovedEventName(token) sm.Emit(eventName) sm.RemoveAllListeners(eventName) } else { - pfxlog.Logger().Debugf("could not remove network session [%s]; not found", token) + pfxlog.Logger().Debugf("could not remove session [token: %s]; not found", token) } } @@ -245,7 +267,7 @@ func (sm *StateManagerImpl) GetSession(token string) *edge_ctrl_pb.Session { if ns, ok := obj.(*edge_ctrl_pb.Session); ok { return ns } - pfxlog.Logger().Panic("encountered non-network session in network session map") + pfxlog.Logger().Panic("encountered non-session in network session map") } return nil diff --git a/router/xgress_edge/factory.go b/router/xgress_edge/factory.go index be7c43a6f..03a599341 100644 --- a/router/xgress_edge/factory.go +++ b/router/xgress_edge/factory.go @@ -81,11 +81,11 @@ func (factory *Factory) BindChannel(ch channel2.Channel) error { } ch.AddReceiveHandler(handler_edge_ctrl.NewHelloHandler(hostname, supportedProtocols, protocolPorts)) - ch.AddReceiveHandler(handler_edge_ctrl.NewSessionAddedHandler(factory.stateManager)) + ch.AddReceiveHandler(handler_edge_ctrl.NewSessionAddedHandler(factory.stateManager, ch)) ch.AddReceiveHandler(handler_edge_ctrl.NewSessionRemovedHandler(factory.stateManager)) ch.AddReceiveHandler(handler_edge_ctrl.NewSessionUpdatedHandler(factory.stateManager)) - ch.AddReceiveHandler(handler_edge_ctrl.NewApiSessionAddedHandler(factory.stateManager)) + ch.AddReceiveHandler(handler_edge_ctrl.NewApiSessionAddedHandler(factory.stateManager, ch)) ch.AddReceiveHandler(handler_edge_ctrl.NewApiSessionRemovedHandler(factory.stateManager)) ch.AddReceiveHandler(handler_edge_ctrl.NewApiSessionUpdatedHandler(factory.stateManager)) return nil diff --git a/specs/swagger.yml b/specs/swagger.yml index 3931f95b1..af2fed635 100644 --- a/specs/swagger.yml +++ b/specs/swagger.yml @@ -5197,6 +5197,7 @@ definitions: - arch - buildDate - revision + - syncStatus properties: name: type: string @@ -5228,6 +5229,8 @@ definitions: $ref: '#/definitions/attributes' fingerprint: type: string + syncStatus: + type: string versionInfo: $ref: '#/definitions/versionInfo' example: diff --git a/tests/accept_manual_start_test.go b/tests/accept_manual_start_test.go index 773e9577c..bf3e4aca3 100644 --- a/tests/accept_manual_start_test.go +++ b/tests/accept_manual_start_test.go @@ -49,6 +49,8 @@ func Test_ManualStart(t *testing.T) { log.Info("starting listener1") host1 := &host{} host1.id, host1.context = ctx.AdminSession.RequireCreateSdkContext() + defer host1.context.Close() + listener, err := host1.context.ListenWithOptions(service.Name, &ziti.ListenOptions{ Precedence: ziti.PrecedenceRequired, ManualStart: true, @@ -63,6 +65,8 @@ func Test_ManualStart(t *testing.T) { log.Info("starting listener2") host2 := &host{} host2.id, host2.context = ctx.AdminSession.RequireCreateSdkContext() + defer host2.context.Close() + listener, err = host2.context.ListenWithOptions(service.Name, &ziti.ListenOptions{ Precedence: ziti.PrecedenceDefault, ManualStart: false, @@ -116,6 +120,8 @@ func Test_ManualStart(t *testing.T) { }() _, context := ctx.AdminSession.RequireCreateSdkContext() + defer context.Close() + for i := 0; i < 10; i++ { log.Infof("dialing: %v", i) conn := ctx.WrapConn(context.Dial(service.Name)) diff --git a/tests/addressable_terminators_test.go b/tests/addressable_terminators_test.go index 3938a648c..a73daddff 100644 --- a/tests/addressable_terminators_test.go +++ b/tests/addressable_terminators_test.go @@ -52,6 +52,8 @@ func Test_AddressableTerminators(t *testing.T) { hosts = append(hosts, host) host.id, host.context = ctx.AdminSession.RequireCreateSdkContext() + defer host.context.Close() + host.listener, err = host.context.ListenWithOptions(service.Name, &ziti.ListenOptions{ BindUsingEdgeIdentity: true, }) @@ -69,6 +71,7 @@ func Test_AddressableTerminators(t *testing.T) { client := &client{} clients = append(clients, client) client.id, client.context = ctx.AdminSession.RequireCreateSdkContext() + defer client.context.Close() } waitForConn := func(listener net.Listener, timeout time.Duration) (net.Conn, error) { @@ -127,6 +130,8 @@ func Test_AddressableTerminatorSameIdentity(t *testing.T) { } identity, context := ctx.AdminSession.RequireCreateSdkContext() + defer context.Close() + listener, err := context.ListenWithOptions(service.Name, &ziti.ListenOptions{ BindUsingEdgeIdentity: true, ConnectTimeout: 5 * time.Second, @@ -171,6 +176,8 @@ func Test_AddressableTerminatorDifferentIdentity(t *testing.T) { } _, context := ctx.AdminSession.RequireCreateSdkContext() + defer context.Close() + listener, err := context.ListenWithOptions(service.Name, &ziti.ListenOptions{ Identity: "foobar", ConnectTimeout: 5 * time.Second, @@ -180,6 +187,8 @@ func Test_AddressableTerminatorDifferentIdentity(t *testing.T) { defer func() { _ = listener.Close() }() _, context2 := ctx.AdminSession.RequireCreateSdkContext() + defer context2.Close() + listener2, err := context2.ListenWithOptions(service.Name, &ziti.ListenOptions{ Identity: "foobar", ConnectTimeout: 5 * time.Second, diff --git a/tests/data_flow_close_test.go b/tests/data_flow_close_test.go index b1d4f2377..eb4353158 100644 --- a/tests/data_flow_close_test.go +++ b/tests/data_flow_close_test.go @@ -39,6 +39,8 @@ func Test_ServerConnClosePropagation(t *testing.T) { service := ctx.AdminSession.RequireNewServiceAccessibleToAll("smartrouting") _, context := ctx.AdminSession.RequireCreateSdkContext() + defer context.Close() + listener, err := context.Listen(service.Name) ctx.Req.NoError(err) @@ -69,6 +71,8 @@ func Test_ServerConnClosePropagation(t *testing.T) { clientContext := ziti.NewContextWithConfig(clientConfig) conn := ctx.WrapConn(clientContext.Dial(service.Name)) + defer conn.Close() + name := eid.New() conn.WriteString(name, time.Second) conn.ReadExpected("hello, "+name, time.Second) @@ -97,7 +101,11 @@ func Test_ServerContextClosePropagation(t *testing.T) { service := ctx.AdminSession.RequireNewServiceAccessibleToAll("smartrouting") _, context := ctx.AdminSession.RequireCreateSdkContext() + defer context.Close() + listener, err := context.Listen(service.Name) + defer listener.Close() + ctx.Req.NoError(err) errC := make(chan error, 1) @@ -128,6 +136,8 @@ func Test_ServerContextClosePropagation(t *testing.T) { clientContext := ziti.NewContextWithConfig(clientConfig) conn := ctx.WrapConn(clientContext.Dial(service.Name)) + defer conn.Close() + name := eid.New() conn.WriteString(name, time.Second) conn.ReadExpected("hello, "+name, time.Second) @@ -157,7 +167,11 @@ func Test_ServerCloseListenerPropagation(t *testing.T) { service := ctx.AdminSession.RequireNewServiceAccessibleToAll("smartrouting") _, context := ctx.AdminSession.RequireCreateSdkContext() + defer context.Close() + listener, err := context.Listen(service.Name) + defer listener.Close() + ctx.Req.NoError(err) errC := make(chan error, 1) @@ -190,6 +204,8 @@ func Test_ServerCloseListenerPropagation(t *testing.T) { clientContext := ziti.NewContextWithConfig(clientConfig) conn := ctx.WrapConn(clientContext.Dial(service.Name)) + defer conn.Close() + name := eid.New() conn.WriteString(name, time.Second) conn.ReadExpected("hello, "+name, time.Second) @@ -209,8 +225,11 @@ func Test_ClientConnClosePropagation(t *testing.T) { service := ctx.AdminSession.RequireNewServiceAccessibleToAll("smartrouting") _, context := ctx.AdminSession.RequireCreateSdkContext() + defer context.Close() + listener, err := context.Listen(service.Name) ctx.Req.NoError(err) + defer listener.Close() clientIdentity := ctx.AdminSession.RequireNewIdentityWithOtt(false) clientConfig := ctx.EnrollIdentity(clientIdentity.Id) @@ -268,8 +287,11 @@ func Test_ClientContextClosePropagation(t *testing.T) { service := ctx.AdminSession.RequireNewServiceAccessibleToAll("smartrouting") _, context := ctx.AdminSession.RequireCreateSdkContext() + defer context.Close() + listener, err := context.Listen(service.Name) ctx.Req.NoError(err) + defer listener.Close() clientIdentity := ctx.AdminSession.RequireNewIdentityWithOtt(false) clientConfig := ctx.EnrollIdentity(clientIdentity.Id) @@ -328,8 +350,11 @@ func Test_ServerConnCloseWritePropagation(t *testing.T) { service := ctx.AdminSession.RequireNewServiceAccessibleToAll("smartrouting") _, context := ctx.AdminSession.RequireCreateSdkContext() + defer context.Close() + listener, err := context.Listen(service.Name) ctx.Req.NoError(err) + defer listener.Close() clientIdentity := ctx.AdminSession.RequireNewIdentityWithOtt(false) clientConfig := ctx.EnrollIdentity(clientIdentity.Id) @@ -393,8 +418,11 @@ func Test_ClientConnCloseWritePropagation(t *testing.T) { service := ctx.AdminSession.RequireNewServiceAccessibleToAll("smartrouting") _, context := ctx.AdminSession.RequireCreateSdkContext() + defer context.Close() + listener, err := context.Listen(service.Name) ctx.Req.NoError(err) + defer listener.Close() defer func() { ctx.Req.NoError(listener.Close()) diff --git a/tests/data_flow_hs_rotating_test.go b/tests/data_flow_hs_rotating_test.go index 8bf8ae8c9..cfd06e735 100644 --- a/tests/data_flow_hs_rotating_test.go +++ b/tests/data_flow_hs_rotating_test.go @@ -73,6 +73,8 @@ func testClientFirstWithStrategy(t *testing.T, strategy string) { var serverContexts []ziti.Context for i := 0; i < 3; i++ { _, context := ctx.AdminSession.RequireCreateSdkContext() + defer context.Close() + serverContexts = append(serverContexts, context) serverContextC <- context } @@ -220,6 +222,8 @@ func testServerFirstWithStrategy(t *testing.T, strategy string) { for i := 0; i < 3; i++ { _, context := ctx.AdminSession.RequireCreateSdkContext() + defer context.Close() + serverContexts = append(serverContexts, context) serverContextC <- context } @@ -279,6 +283,8 @@ func testServerFirstWithStrategy(t *testing.T, strategy string) { } conn := ctx.WrapConn(clientContext.Dial(service.Name)) + defer conn.Close() + name := conn.ReadString(1024, time.Second) conn.WriteString("hello, "+name, time.Second) logger.Debugf("%v: done", i+1) diff --git a/tests/data_flow_hs_test.go b/tests/data_flow_hs_test.go index c4d451808..23a4f622e 100644 --- a/tests/data_flow_hs_test.go +++ b/tests/data_flow_hs_test.go @@ -38,12 +38,17 @@ func Test_HSDataflow(t *testing.T) { ctx.CreateEnrollAndStartEdgeRouter() _, hostContext1 := ctx.AdminSession.RequireCreateSdkContext() + defer hostContext1.Close() + listener1, err := hostContext1.Listen(service.Name) ctx.Req.NoError(err) _, hostContext2 := ctx.AdminSession.RequireCreateSdkContext() + defer hostContext2.Close() + listener2, err := hostContext2.Listen(service.Name) ctx.Req.NoError(err) + defer listener2.Close() serverHandler := func(conn *testServerConn) error { for { diff --git a/tests/data_flow_test.go b/tests/data_flow_test.go index ceb4bd7e6..255bb9236 100644 --- a/tests/data_flow_test.go +++ b/tests/data_flow_test.go @@ -35,8 +35,11 @@ func Test_Dataflow(t *testing.T) { ctx.CreateEnrollAndStartEdgeRouter() _, hostContext := ctx.AdminSession.RequireCreateSdkContext() + defer hostContext.Close() + listener, err := hostContext.Listen(service.Name) ctx.Req.NoError(err) + defer listener.Close() testServer := newTestServer(listener, func(conn *testServerConn) error { for { @@ -57,7 +60,10 @@ func Test_Dataflow(t *testing.T) { testServer.start() _, clientContext := ctx.AdminSession.RequireCreateSdkContext() + defer clientContext.Close() + conn := ctx.WrapConn(clientContext.Dial(service.Name)) + defer conn.Close() name := eid.New() conn.WriteString(name, time.Second)