chore: simplify sync impl by abstracting bidirectional transport (#844)
Release Please / release-please (push) Has been cancelled
Build Snapshot Release / build (push) Has been cancelled
Test / test-nix (push) Has been cancelled
Test / test-win (push) Has been cancelled
Update Restic / update-restic-version (push) Has been cancelled

This commit is contained in:
Gareth
2025-07-21 21:20:16 -07:00
committed by GitHub
parent 85ec74fdb3
commit 86e624bb73
14 changed files with 1535 additions and 327 deletions
+384 -275
View File
@@ -11,6 +11,7 @@ import (
_ "google.golang.org/genproto/googleapis/api/annotations"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
anypb "google.golang.org/protobuf/types/known/anypb"
_ "google.golang.org/protobuf/types/known/emptypb"
reflect "reflect"
sync "sync"
@@ -139,7 +140,92 @@ func (x SyncStreamItem_RepoConnectionState) Number() protoreflect.EnumNumber {
// Deprecated: Use SyncStreamItem_RepoConnectionState.Descriptor instead.
func (SyncStreamItem_RepoConnectionState) EnumDescriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{2, 0}
return file_v1_syncservice_proto_rawDescGZIP(), []int{3, 0}
}
type TunnelMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ConnId int64 `protobuf:"varint,1,opt,name=conn_id,json=connId,proto3" json:"conn_id,omitempty"` // The connection ID this request belongs to, enables multiplexing.
Seqno int64 `protobuf:"varint,2,opt,name=seqno,proto3" json:"seqno,omitempty"`
Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` // The data to send, this is a raw byte stream.
Close bool `protobuf:"varint,4,opt,name=close,proto3" json:"close,omitempty"` // If true, the write end should be closed after this request.
PubkeyEcdhX25519 []byte `protobuf:"bytes,100,opt,name=pubkey_ecdh_x25519,json=pubkeyEcdhX25519,proto3" json:"pubkey_ecdh_x25519,omitempty"` // The public key used for ECDH key exchange, binary encoded.
Any *anypb.Any `protobuf:"bytes,1000,opt,name=any,proto3" json:"any,omitempty"` // Available to allow sending custom data down the tunnel in the initial handshake.
}
func (x *TunnelMessage) Reset() {
*x = TunnelMessage{}
mi := &file_v1_syncservice_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *TunnelMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TunnelMessage) ProtoMessage() {}
func (x *TunnelMessage) ProtoReflect() protoreflect.Message {
mi := &file_v1_syncservice_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use TunnelMessage.ProtoReflect.Descriptor instead.
func (*TunnelMessage) Descriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{0}
}
func (x *TunnelMessage) GetConnId() int64 {
if x != nil {
return x.ConnId
}
return 0
}
func (x *TunnelMessage) GetSeqno() int64 {
if x != nil {
return x.Seqno
}
return 0
}
func (x *TunnelMessage) GetData() []byte {
if x != nil {
return x.Data
}
return nil
}
func (x *TunnelMessage) GetClose() bool {
if x != nil {
return x.Close
}
return false
}
func (x *TunnelMessage) GetPubkeyEcdhX25519() []byte {
if x != nil {
return x.PubkeyEcdhX25519
}
return nil
}
func (x *TunnelMessage) GetAny() *anypb.Any {
if x != nil {
return x.Any
}
return nil
}
type SyncStateStreamRequest struct {
@@ -152,7 +238,7 @@ type SyncStateStreamRequest struct {
func (x *SyncStateStreamRequest) Reset() {
*x = SyncStateStreamRequest{}
mi := &file_v1_syncservice_proto_msgTypes[0]
mi := &file_v1_syncservice_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -164,7 +250,7 @@ func (x *SyncStateStreamRequest) String() string {
func (*SyncStateStreamRequest) ProtoMessage() {}
func (x *SyncStateStreamRequest) ProtoReflect() protoreflect.Message {
mi := &file_v1_syncservice_proto_msgTypes[0]
mi := &file_v1_syncservice_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -177,7 +263,7 @@ func (x *SyncStateStreamRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use SyncStateStreamRequest.ProtoReflect.Descriptor instead.
func (*SyncStateStreamRequest) Descriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{0}
return file_v1_syncservice_proto_rawDescGZIP(), []int{1}
}
func (x *SyncStateStreamRequest) GetSubscribe() bool {
@@ -204,7 +290,7 @@ type PeerState struct {
func (x *PeerState) Reset() {
*x = PeerState{}
mi := &file_v1_syncservice_proto_msgTypes[1]
mi := &file_v1_syncservice_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -216,7 +302,7 @@ func (x *PeerState) String() string {
func (*PeerState) ProtoMessage() {}
func (x *PeerState) ProtoReflect() protoreflect.Message {
mi := &file_v1_syncservice_proto_msgTypes[1]
mi := &file_v1_syncservice_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -229,7 +315,7 @@ func (x *PeerState) ProtoReflect() protoreflect.Message {
// Deprecated: Use PeerState.ProtoReflect.Descriptor instead.
func (*PeerState) Descriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{1}
return file_v1_syncservice_proto_rawDescGZIP(), []int{2}
}
func (x *PeerState) GetPeerInstanceId() string {
@@ -309,7 +395,7 @@ type SyncStreamItem struct {
func (x *SyncStreamItem) Reset() {
*x = SyncStreamItem{}
mi := &file_v1_syncservice_proto_msgTypes[2]
mi := &file_v1_syncservice_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -321,7 +407,7 @@ func (x *SyncStreamItem) String() string {
func (*SyncStreamItem) ProtoMessage() {}
func (x *SyncStreamItem) ProtoReflect() protoreflect.Message {
mi := &file_v1_syncservice_proto_msgTypes[2]
mi := &file_v1_syncservice_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -334,7 +420,7 @@ func (x *SyncStreamItem) ProtoReflect() protoreflect.Message {
// Deprecated: Use SyncStreamItem.ProtoReflect.Descriptor instead.
func (*SyncStreamItem) Descriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{2}
return file_v1_syncservice_proto_rawDescGZIP(), []int{3}
}
func (m *SyncStreamItem) GetAction() isSyncStreamItem_Action {
@@ -479,7 +565,7 @@ type RemoteConfig struct {
func (x *RemoteConfig) Reset() {
*x = RemoteConfig{}
mi := &file_v1_syncservice_proto_msgTypes[3]
mi := &file_v1_syncservice_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -491,7 +577,7 @@ func (x *RemoteConfig) String() string {
func (*RemoteConfig) ProtoMessage() {}
func (x *RemoteConfig) ProtoReflect() protoreflect.Message {
mi := &file_v1_syncservice_proto_msgTypes[3]
mi := &file_v1_syncservice_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -504,7 +590,7 @@ func (x *RemoteConfig) ProtoReflect() protoreflect.Message {
// Deprecated: Use RemoteConfig.ProtoReflect.Descriptor instead.
func (*RemoteConfig) Descriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{3}
return file_v1_syncservice_proto_rawDescGZIP(), []int{4}
}
func (x *RemoteConfig) GetModno() int32 {
@@ -547,7 +633,7 @@ type SyncStreamItem_SyncActionHandshake struct {
func (x *SyncStreamItem_SyncActionHandshake) Reset() {
*x = SyncStreamItem_SyncActionHandshake{}
mi := &file_v1_syncservice_proto_msgTypes[4]
mi := &file_v1_syncservice_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -559,7 +645,7 @@ func (x *SyncStreamItem_SyncActionHandshake) String() string {
func (*SyncStreamItem_SyncActionHandshake) ProtoMessage() {}
func (x *SyncStreamItem_SyncActionHandshake) ProtoReflect() protoreflect.Message {
mi := &file_v1_syncservice_proto_msgTypes[4]
mi := &file_v1_syncservice_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -572,7 +658,7 @@ func (x *SyncStreamItem_SyncActionHandshake) ProtoReflect() protoreflect.Message
// Deprecated: Use SyncStreamItem_SyncActionHandshake.ProtoReflect.Descriptor instead.
func (*SyncStreamItem_SyncActionHandshake) Descriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{2, 0}
return file_v1_syncservice_proto_rawDescGZIP(), []int{3, 0}
}
func (x *SyncStreamItem_SyncActionHandshake) GetProtocolVersion() int64 {
@@ -605,7 +691,7 @@ type SyncStreamItem_SyncActionHeartbeat struct {
func (x *SyncStreamItem_SyncActionHeartbeat) Reset() {
*x = SyncStreamItem_SyncActionHeartbeat{}
mi := &file_v1_syncservice_proto_msgTypes[5]
mi := &file_v1_syncservice_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -617,7 +703,7 @@ func (x *SyncStreamItem_SyncActionHeartbeat) String() string {
func (*SyncStreamItem_SyncActionHeartbeat) ProtoMessage() {}
func (x *SyncStreamItem_SyncActionHeartbeat) ProtoReflect() protoreflect.Message {
mi := &file_v1_syncservice_proto_msgTypes[5]
mi := &file_v1_syncservice_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -630,7 +716,7 @@ func (x *SyncStreamItem_SyncActionHeartbeat) ProtoReflect() protoreflect.Message
// Deprecated: Use SyncStreamItem_SyncActionHeartbeat.ProtoReflect.Descriptor instead.
func (*SyncStreamItem_SyncActionHeartbeat) Descriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{2, 1}
return file_v1_syncservice_proto_rawDescGZIP(), []int{3, 1}
}
type SyncStreamItem_SyncActionSendConfig struct {
@@ -643,7 +729,7 @@ type SyncStreamItem_SyncActionSendConfig struct {
func (x *SyncStreamItem_SyncActionSendConfig) Reset() {
*x = SyncStreamItem_SyncActionSendConfig{}
mi := &file_v1_syncservice_proto_msgTypes[6]
mi := &file_v1_syncservice_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -655,7 +741,7 @@ func (x *SyncStreamItem_SyncActionSendConfig) String() string {
func (*SyncStreamItem_SyncActionSendConfig) ProtoMessage() {}
func (x *SyncStreamItem_SyncActionSendConfig) ProtoReflect() protoreflect.Message {
mi := &file_v1_syncservice_proto_msgTypes[6]
mi := &file_v1_syncservice_proto_msgTypes[7]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -668,7 +754,7 @@ func (x *SyncStreamItem_SyncActionSendConfig) ProtoReflect() protoreflect.Messag
// Deprecated: Use SyncStreamItem_SyncActionSendConfig.ProtoReflect.Descriptor instead.
func (*SyncStreamItem_SyncActionSendConfig) Descriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{2, 2}
return file_v1_syncservice_proto_rawDescGZIP(), []int{3, 2}
}
func (x *SyncStreamItem_SyncActionSendConfig) GetConfig() *RemoteConfig {
@@ -691,7 +777,7 @@ type SyncStreamItem_SyncActionSetConfig struct {
func (x *SyncStreamItem_SyncActionSetConfig) Reset() {
*x = SyncStreamItem_SyncActionSetConfig{}
mi := &file_v1_syncservice_proto_msgTypes[7]
mi := &file_v1_syncservice_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -703,7 +789,7 @@ func (x *SyncStreamItem_SyncActionSetConfig) String() string {
func (*SyncStreamItem_SyncActionSetConfig) ProtoMessage() {}
func (x *SyncStreamItem_SyncActionSetConfig) ProtoReflect() protoreflect.Message {
mi := &file_v1_syncservice_proto_msgTypes[7]
mi := &file_v1_syncservice_proto_msgTypes[8]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -716,7 +802,7 @@ func (x *SyncStreamItem_SyncActionSetConfig) ProtoReflect() protoreflect.Message
// Deprecated: Use SyncStreamItem_SyncActionSetConfig.ProtoReflect.Descriptor instead.
func (*SyncStreamItem_SyncActionSetConfig) Descriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{2, 3}
return file_v1_syncservice_proto_rawDescGZIP(), []int{3, 3}
}
func (x *SyncStreamItem_SyncActionSetConfig) GetRepos() []*Repo {
@@ -758,7 +844,7 @@ type SyncStreamItem_SyncActionListResources struct {
func (x *SyncStreamItem_SyncActionListResources) Reset() {
*x = SyncStreamItem_SyncActionListResources{}
mi := &file_v1_syncservice_proto_msgTypes[8]
mi := &file_v1_syncservice_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -770,7 +856,7 @@ func (x *SyncStreamItem_SyncActionListResources) String() string {
func (*SyncStreamItem_SyncActionListResources) ProtoMessage() {}
func (x *SyncStreamItem_SyncActionListResources) ProtoReflect() protoreflect.Message {
mi := &file_v1_syncservice_proto_msgTypes[8]
mi := &file_v1_syncservice_proto_msgTypes[9]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -783,7 +869,7 @@ func (x *SyncStreamItem_SyncActionListResources) ProtoReflect() protoreflect.Mes
// Deprecated: Use SyncStreamItem_SyncActionListResources.ProtoReflect.Descriptor instead.
func (*SyncStreamItem_SyncActionListResources) Descriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{2, 4}
return file_v1_syncservice_proto_rawDescGZIP(), []int{3, 4}
}
func (x *SyncStreamItem_SyncActionListResources) GetRepoIds() []string {
@@ -810,7 +896,7 @@ type SyncStreamItem_SyncActionConnectRepo struct {
func (x *SyncStreamItem_SyncActionConnectRepo) Reset() {
*x = SyncStreamItem_SyncActionConnectRepo{}
mi := &file_v1_syncservice_proto_msgTypes[9]
mi := &file_v1_syncservice_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -822,7 +908,7 @@ func (x *SyncStreamItem_SyncActionConnectRepo) String() string {
func (*SyncStreamItem_SyncActionConnectRepo) ProtoMessage() {}
func (x *SyncStreamItem_SyncActionConnectRepo) ProtoReflect() protoreflect.Message {
mi := &file_v1_syncservice_proto_msgTypes[9]
mi := &file_v1_syncservice_proto_msgTypes[10]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -835,7 +921,7 @@ func (x *SyncStreamItem_SyncActionConnectRepo) ProtoReflect() protoreflect.Messa
// Deprecated: Use SyncStreamItem_SyncActionConnectRepo.ProtoReflect.Descriptor instead.
func (*SyncStreamItem_SyncActionConnectRepo) Descriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{2, 5}
return file_v1_syncservice_proto_rawDescGZIP(), []int{3, 5}
}
func (x *SyncStreamItem_SyncActionConnectRepo) GetRepoId() string {
@@ -861,7 +947,7 @@ type SyncStreamItem_SyncActionDiffOperations struct {
func (x *SyncStreamItem_SyncActionDiffOperations) Reset() {
*x = SyncStreamItem_SyncActionDiffOperations{}
mi := &file_v1_syncservice_proto_msgTypes[10]
mi := &file_v1_syncservice_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -873,7 +959,7 @@ func (x *SyncStreamItem_SyncActionDiffOperations) String() string {
func (*SyncStreamItem_SyncActionDiffOperations) ProtoMessage() {}
func (x *SyncStreamItem_SyncActionDiffOperations) ProtoReflect() protoreflect.Message {
mi := &file_v1_syncservice_proto_msgTypes[10]
mi := &file_v1_syncservice_proto_msgTypes[11]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -886,7 +972,7 @@ func (x *SyncStreamItem_SyncActionDiffOperations) ProtoReflect() protoreflect.Me
// Deprecated: Use SyncStreamItem_SyncActionDiffOperations.ProtoReflect.Descriptor instead.
func (*SyncStreamItem_SyncActionDiffOperations) Descriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{2, 6}
return file_v1_syncservice_proto_rawDescGZIP(), []int{3, 6}
}
func (x *SyncStreamItem_SyncActionDiffOperations) GetHaveOperationsSelector() *OpSelector {
@@ -927,7 +1013,7 @@ type SyncStreamItem_SyncActionSendOperations struct {
func (x *SyncStreamItem_SyncActionSendOperations) Reset() {
*x = SyncStreamItem_SyncActionSendOperations{}
mi := &file_v1_syncservice_proto_msgTypes[11]
mi := &file_v1_syncservice_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -939,7 +1025,7 @@ func (x *SyncStreamItem_SyncActionSendOperations) String() string {
func (*SyncStreamItem_SyncActionSendOperations) ProtoMessage() {}
func (x *SyncStreamItem_SyncActionSendOperations) ProtoReflect() protoreflect.Message {
mi := &file_v1_syncservice_proto_msgTypes[11]
mi := &file_v1_syncservice_proto_msgTypes[12]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -952,7 +1038,7 @@ func (x *SyncStreamItem_SyncActionSendOperations) ProtoReflect() protoreflect.Me
// Deprecated: Use SyncStreamItem_SyncActionSendOperations.ProtoReflect.Descriptor instead.
func (*SyncStreamItem_SyncActionSendOperations) Descriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{2, 7}
return file_v1_syncservice_proto_rawDescGZIP(), []int{3, 7}
}
func (x *SyncStreamItem_SyncActionSendOperations) GetEvent() *OperationEvent {
@@ -972,7 +1058,7 @@ type SyncStreamItem_SyncActionThrottle struct {
func (x *SyncStreamItem_SyncActionThrottle) Reset() {
*x = SyncStreamItem_SyncActionThrottle{}
mi := &file_v1_syncservice_proto_msgTypes[12]
mi := &file_v1_syncservice_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -984,7 +1070,7 @@ func (x *SyncStreamItem_SyncActionThrottle) String() string {
func (*SyncStreamItem_SyncActionThrottle) ProtoMessage() {}
func (x *SyncStreamItem_SyncActionThrottle) ProtoReflect() protoreflect.Message {
mi := &file_v1_syncservice_proto_msgTypes[12]
mi := &file_v1_syncservice_proto_msgTypes[13]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -997,7 +1083,7 @@ func (x *SyncStreamItem_SyncActionThrottle) ProtoReflect() protoreflect.Message
// Deprecated: Use SyncStreamItem_SyncActionThrottle.ProtoReflect.Descriptor instead.
func (*SyncStreamItem_SyncActionThrottle) Descriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{2, 8}
return file_v1_syncservice_proto_rawDescGZIP(), []int{3, 8}
}
func (x *SyncStreamItem_SyncActionThrottle) GetDelayMs() int64 {
@@ -1019,7 +1105,7 @@ type SyncStreamItem_SyncEstablishSharedSecret struct {
func (x *SyncStreamItem_SyncEstablishSharedSecret) Reset() {
*x = SyncStreamItem_SyncEstablishSharedSecret{}
mi := &file_v1_syncservice_proto_msgTypes[13]
mi := &file_v1_syncservice_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1031,7 +1117,7 @@ func (x *SyncStreamItem_SyncEstablishSharedSecret) String() string {
func (*SyncStreamItem_SyncEstablishSharedSecret) ProtoMessage() {}
func (x *SyncStreamItem_SyncEstablishSharedSecret) ProtoReflect() protoreflect.Message {
mi := &file_v1_syncservice_proto_msgTypes[13]
mi := &file_v1_syncservice_proto_msgTypes[14]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1044,7 +1130,7 @@ func (x *SyncStreamItem_SyncEstablishSharedSecret) ProtoReflect() protoreflect.M
// Deprecated: Use SyncStreamItem_SyncEstablishSharedSecret.ProtoReflect.Descriptor instead.
func (*SyncStreamItem_SyncEstablishSharedSecret) Descriptor() ([]byte, []int) {
return file_v1_syncservice_proto_rawDescGZIP(), []int{2, 9}
return file_v1_syncservice_proto_rawDescGZIP(), []int{3, 9}
}
func (x *SyncStreamItem_SyncEstablishSharedSecret) GetEd25519() string {
@@ -1069,190 +1155,208 @@ var file_v1_syncservice_proto_rawDesc = []byte{
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69,
0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x22, 0x36, 0x0a, 0x16, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53,
0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09,
0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
0x09, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x22, 0xd7, 0x02, 0x0a, 0x09, 0x50,
0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x70, 0x65, 0x65, 0x72,
0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0e, 0x70, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x69, 0x64,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x65, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x69,
0x64, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e,
0x32, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65,
0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6b, 0x6e, 0x6f, 0x77, 0x6e,
0x5f, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6b, 0x6e,
0x6f, 0x77, 0x6e, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6b, 0x6e, 0x6f, 0x77,
0x6e, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6b,
0x6e, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x12, 0x35, 0x0a, 0x0d, 0x72, 0x65, 0x6d,
0x6f, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x10, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x52, 0x0c, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x12, 0x32, 0x0a, 0x15, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65,
0x61, 0x74, 0x5f, 0x6d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52,
0x13, 0x6c, 0x61, 0x73, 0x74, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x4d, 0x69,
0x6c, 0x6c, 0x69, 0x73, 0x22, 0xcf, 0x0e, 0x0a, 0x0e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x72,
0x65, 0x61, 0x6d, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x3a, 0x0a, 0x0e, 0x73, 0x69, 0x67, 0x6e, 0x65,
0x64, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x11, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x12, 0x46, 0x0a, 0x09, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63,
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x48, 0x00,
0x52, 0x09, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x46, 0x0a, 0x09, 0x68,
0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26,
0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x74,
0x65, 0x6d, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x61,
0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x48, 0x00, 0x52, 0x09, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62,
0x65, 0x61, 0x74, 0x12, 0x56, 0x0a, 0x0f, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x6f, 0x70, 0x65, 0x72,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76,
0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x74, 0x65, 0x6d,
0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x66, 0x66, 0x4f,
0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x0e, 0x64, 0x69, 0x66,
0x66, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x56, 0x0a, 0x0f, 0x73,
0x65, 0x6e, 0x64, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x15,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74,
0x72, 0x65, 0x61, 0x6d, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x48, 0x00, 0x52, 0x0e, 0x73, 0x65, 0x6e, 0x64, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x12, 0x4a, 0x0a, 0x0b, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79,
0x6e, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x53, 0x79, 0x6e,
0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x48, 0x00, 0x52, 0x0a, 0x73, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
0x47, 0x0a, 0x0a, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x18, 0x20,
0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbf, 0x01,
0x0a, 0x0d, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
0x17, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
0x52, 0x06, 0x63, 0x6f, 0x6e, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x65, 0x71, 0x6e,
0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x73, 0x65, 0x71, 0x6e, 0x6f, 0x12, 0x12,
0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61,
0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
0x08, 0x52, 0x05, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x75, 0x62, 0x6b,
0x65, 0x79, 0x5f, 0x65, 0x63, 0x64, 0x68, 0x5f, 0x78, 0x32, 0x35, 0x35, 0x31, 0x39, 0x18, 0x64,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x45, 0x63, 0x64, 0x68,
0x58, 0x32, 0x35, 0x35, 0x31, 0x39, 0x12, 0x27, 0x0a, 0x03, 0x61, 0x6e, 0x79, 0x18, 0xe8, 0x07,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x03, 0x61, 0x6e, 0x79, 0x22,
0x36, 0x0a, 0x16, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65,
0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x75, 0x62,
0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x75,
0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x22, 0xd7, 0x02, 0x0a, 0x09, 0x50, 0x65, 0x65, 0x72,
0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x6e,
0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0e, 0x70, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12,
0x1d, 0x0a, 0x0a, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x69, 0x64, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x65, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x69, 0x64, 0x12, 0x2d,
0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e,
0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x25, 0x0a,
0x0e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18,
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x70, 0x6c,
0x61, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6b, 0x6e, 0x6f, 0x77, 0x6e,
0x50, 0x6c, 0x61, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x72,
0x65, 0x70, 0x6f, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6b, 0x6e, 0x6f, 0x77,
0x6e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x12, 0x35, 0x0a, 0x0d, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65,
0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e,
0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
0x0c, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x32, 0x0a,
0x15, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x5f,
0x6d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x6c, 0x61,
0x73, 0x74, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69,
0x73, 0x22, 0xcf, 0x0e, 0x0a, 0x0e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x49, 0x74, 0x65, 0x6d, 0x12, 0x3a, 0x0a, 0x0e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x6d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76,
0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48,
0x00, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x12, 0x46, 0x0a, 0x09, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x18, 0x03, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x72,
0x65, 0x61, 0x6d, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x09, 0x73,
0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x53, 0x0a, 0x0e, 0x6c, 0x69, 0x73, 0x74,
0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x2a, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x49, 0x74, 0x65, 0x6d, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4c,
0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0d,
0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x44, 0x0a,
0x08, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x18, 0xe8, 0x07, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x25, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x49, 0x74, 0x65, 0x6d, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54,
0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x08, 0x74, 0x68, 0x72, 0x6f, 0x74,
0x74, 0x6c, 0x65, 0x1a, 0xa2, 0x01, 0x0a, 0x13, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x76, 0x31, 0x2e,
0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69,
0x63, 0x4b, 0x65, 0x79, 0x12, 0x32, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x31, 0x2e, 0x53,
0x69, 0x67, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0a, 0x69, 0x6e,
0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x15, 0x0a, 0x13, 0x53, 0x79, 0x6e, 0x63,
0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x1a,
0x40, 0x0a, 0x14, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x6e,
0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d,
0x6f, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x1a, 0xa5, 0x01, 0x0a, 0x13, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1e, 0x0a, 0x05, 0x72, 0x65, 0x70,
0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65,
0x70, 0x6f, 0x52, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x12, 0x1e, 0x0a, 0x05, 0x70, 0x6c, 0x61,
0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c,
0x61, 0x6e, 0x52, 0x05, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x72, 0x65, 0x70,
0x6f, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x03,
0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x54, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74,
0x65, 0x12, 0x26, 0x0a, 0x0f, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x64, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x6c, 0x61, 0x6e,
0x73, 0x54, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x1a, 0x4f, 0x0a, 0x17, 0x53, 0x79, 0x6e,
0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x73,
0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x73, 0x12,
0x19, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
0x09, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x73, 0x1a, 0x30, 0x0a, 0x15, 0x53, 0x79,
0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52,
0x65, 0x70, 0x6f, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x1a, 0xf5, 0x01, 0x0a,
0x18, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x66, 0x66, 0x4f,
0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x48, 0x0a, 0x18, 0x68, 0x61, 0x76,
0x65, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x6c,
0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x76, 0x31,
0x2e, 0x4f, 0x70, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x16, 0x68, 0x61, 0x76,
0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x65, 0x6c, 0x65, 0x63,
0x74, 0x6f, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x68, 0x61, 0x76, 0x65, 0x5f, 0x6f, 0x70, 0x65, 0x72,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x03, 0x52,
0x10, 0x68, 0x61, 0x76, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64,
0x73, 0x12, 0x32, 0x0a, 0x15, 0x68, 0x61, 0x76, 0x65, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x6e, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03,
0x52, 0x13, 0x68, 0x61, 0x76, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d,
0x6f, 0x64, 0x6e, 0x6f, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28,
0x03, 0x52, 0x11, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x44, 0x0a, 0x18, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x12, 0x28, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x12, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76,
0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x2f, 0x0a, 0x12, 0x53, 0x79,
0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65,
0x12, 0x19, 0x0a, 0x08, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01,
0x28, 0x03, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x1a, 0x38, 0x0a, 0x19, 0x53,
0x79, 0x6e, 0x63, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x53, 0x68, 0x61, 0x72,
0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x07, 0x65, 0x64, 0x32, 0x35,
0x35, 0x31, 0x39, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x64, 0x32, 0x35, 0x35,
0x31, 0x39, 0x70, 0x75, 0x62, 0x22, 0xb4, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6f,
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a,
0x18, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54,
0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x43,
0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f,
0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x4e,
0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f,
0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x4f, 0x4e,
0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e,
0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x5a, 0x45, 0x44, 0x10, 0x03, 0x12, 0x1e, 0x0a, 0x1a,
0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45,
0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x04, 0x42, 0x08, 0x0a, 0x06,
0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7e, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65,
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x6e, 0x6f, 0x18,
0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x6e, 0x6f, 0x12, 0x18, 0x0a, 0x07,
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x18,
0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x52,
0x6f, 0x6e, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x48, 0x00, 0x52, 0x09, 0x68,
0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x46, 0x0a, 0x09, 0x68, 0x65, 0x61, 0x72,
0x74, 0x62, 0x65, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x76, 0x31,
0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x74, 0x65, 0x6d, 0x2e,
0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62,
0x65, 0x61, 0x74, 0x48, 0x00, 0x52, 0x09, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74,
0x12, 0x56, 0x0a, 0x0f, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76, 0x31, 0x2e, 0x53,
0x79, 0x6e, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x53, 0x79,
0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x66, 0x66, 0x4f, 0x70, 0x65, 0x72,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x0e, 0x64, 0x69, 0x66, 0x66, 0x4f, 0x70,
0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x56, 0x0a, 0x0f, 0x73, 0x65, 0x6e, 0x64,
0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x15, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x2b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x53, 0x65, 0x6e, 0x64, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x48, 0x00,
0x52, 0x0e, 0x73, 0x65, 0x6e, 0x64, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x12, 0x4a, 0x0a, 0x0b, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18,
0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53,
0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00,
0x52, 0x0a, 0x73, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x47, 0x0a, 0x0a,
0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x26, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x49, 0x74, 0x65, 0x6d, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53,
0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x09, 0x73, 0x65, 0x74, 0x43,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x53, 0x0a, 0x0e, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e,
0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x74, 0x65,
0x6d, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74,
0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0d, 0x6c, 0x69, 0x73,
0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x08, 0x74, 0x68,
0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x18, 0xe8, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e,
0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x74, 0x65,
0x6d, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x68, 0x72, 0x6f,
0x74, 0x74, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x08, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65,
0x1a, 0xa2, 0x01, 0x0a, 0x13, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48,
0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x63, 0x6f, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
0x28, 0x03, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65,
0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62,
0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65,
0x79, 0x12, 0x32, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e,
0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61,
0x6e, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x15, 0x0a, 0x13, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x1a, 0x40, 0x0a, 0x14,
0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65,
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0xa5,
0x01, 0x0a, 0x13, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74,
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1e, 0x0a, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x18,
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x52,
0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x12, 0x1e, 0x0a, 0x05, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x18,
0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x52,
0x05, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x2a, 0xa0, 0x02, 0x0a, 0x13, 0x53, 0x79, 0x6e, 0x63, 0x43,
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c,
0x0a, 0x18, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41,
0x54, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18,
0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x52,
0x05, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x5f,
0x74, 0x6f, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52,
0x0d, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x54, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x26,
0x0a, 0x0f, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74,
0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x54, 0x6f,
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x1a, 0x4f, 0x0a, 0x17, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x73, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20,
0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x73, 0x12, 0x19, 0x0a, 0x08,
0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07,
0x70, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x73, 0x1a, 0x30, 0x0a, 0x15, 0x53, 0x79, 0x6e, 0x63, 0x41,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x70, 0x6f,
0x12, 0x17, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x1a, 0xf5, 0x01, 0x0a, 0x18, 0x53, 0x79,
0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x66, 0x66, 0x4f, 0x70, 0x65, 0x72,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x48, 0x0a, 0x18, 0x68, 0x61, 0x76, 0x65, 0x5f, 0x6f,
0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74,
0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70,
0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x16, 0x68, 0x61, 0x76, 0x65, 0x4f, 0x70,
0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72,
0x12, 0x2c, 0x0a, 0x12, 0x68, 0x61, 0x76, 0x65, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x03, 0x52, 0x10, 0x68, 0x61,
0x76, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x32,
0x0a, 0x15, 0x68, 0x61, 0x76, 0x65, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x5f, 0x6d, 0x6f, 0x64, 0x6e, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x13, 0x68,
0x61, 0x76, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x6e,
0x6f, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6f, 0x70,
0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x03, 0x52, 0x11,
0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x1a, 0x44, 0x0a, 0x18, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53,
0x65, 0x6e, 0x64, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x28, 0x0a,
0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x76,
0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74,
0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x2f, 0x0a, 0x12, 0x53, 0x79, 0x6e, 0x63, 0x41,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x12, 0x19, 0x0a,
0x08, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
0x07, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x1a, 0x38, 0x0a, 0x19, 0x53, 0x79, 0x6e, 0x63,
0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53,
0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x07, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x70,
0x75, 0x62, 0x22, 0xb4, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f,
0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55,
0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4e, 0x4e,
0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x45, 0x4e,
0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43,
0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45,
0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43,
0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54,
0x48, 0x4f, 0x52, 0x49, 0x5a, 0x45, 0x44, 0x10, 0x03, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x4e,
0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x4e, 0x4f,
0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x04, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x22, 0x7e, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x6e, 0x6f, 0x18, 0x01, 0x20, 0x01,
0x28, 0x05, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x6e, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x52, 0x05, 0x72, 0x65,
0x70, 0x6f, 0x73, 0x12, 0x1e, 0x0a, 0x05, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x05, 0x70, 0x6c,
0x61, 0x6e, 0x73, 0x2a, 0xa0, 0x02, 0x0a, 0x13, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6e, 0x6e,
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x43,
0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f,
0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4e,
0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x45,
0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x4e, 0x4e, 0x45,
0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x4e,
0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x4f, 0x4e, 0x4e, 0x45,
0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x44, 0x49, 0x53, 0x43,
0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f,
0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52,
0x45, 0x54, 0x52, 0x59, 0x5f, 0x57, 0x41, 0x49, 0x54, 0x10, 0x04, 0x12, 0x1f, 0x0a, 0x1b, 0x43,
0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f,
0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x10, 0x0a, 0x12, 0x23, 0x0a, 0x1f,
0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45,
0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f,
0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43,
0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x4f,
0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x44,
0x49, 0x53, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x1f, 0x0a,
0x1b, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54,
0x45, 0x5f, 0x52, 0x45, 0x54, 0x52, 0x59, 0x5f, 0x57, 0x41, 0x49, 0x54, 0x10, 0x04, 0x12, 0x1f,
0x0a, 0x1b, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41,
0x54, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x10, 0x0a, 0x12,
0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54,
0x41, 0x54, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43,
0x4f, 0x4c, 0x10, 0x0b, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49,
0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49,
0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x0c, 0x32, 0x4b, 0x0a, 0x13, 0x42, 0x61, 0x63,
0x6b, 0x72, 0x65, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x12, 0x34, 0x0a, 0x04, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79,
0x6e, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x74, 0x65, 0x6d, 0x1a, 0x12, 0x2e, 0x76,
0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x10,
0x0b, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f,
0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x45,
0x52, 0x4e, 0x41, 0x4c, 0x10, 0x0c, 0x32, 0x45, 0x0a, 0x0d, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x06, 0x54, 0x75, 0x6e, 0x6e, 0x65,
0x6c, 0x12, 0x11, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x1a, 0x11, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x32, 0x4b, 0x0a,
0x13, 0x42, 0x61, 0x63, 0x6b, 0x72, 0x65, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x65, 0x72,
0x76, 0x69, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x04, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x12, 0x2e, 0x76,
0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x74, 0x65, 0x6d,
0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x32, 0x64, 0x0a, 0x18, 0x42, 0x61, 0x63, 0x6b, 0x72, 0x65,
0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x12, 0x48, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x50, 0x65, 0x65, 0x72, 0x53, 0x79, 0x6e,
0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1a, 0x2e,
0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65,
0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e, 0x76, 0x31, 0x2e, 0x50,
0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x00, 0x30, 0x01, 0x42, 0x2c, 0x5a, 0x2a,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x65, 0x74,
0x68, 0x67, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x72, 0x65, 0x73, 0x74,
0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
0x1a, 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x49, 0x74, 0x65, 0x6d, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x32, 0x64, 0x0a, 0x18, 0x42, 0x61,
0x63, 0x6b, 0x72, 0x65, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x50, 0x65, 0x65,
0x72, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x12, 0x1a, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65,
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0d, 0x2e,
0x76, 0x31, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x00, 0x30, 0x01,
0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67,
0x61, 0x72, 0x65, 0x74, 0x68, 0x67, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x2f, 0x62, 0x61, 0x63, 0x6b,
0x72, 0x65, 0x73, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1268,61 +1372,66 @@ func file_v1_syncservice_proto_rawDescGZIP() []byte {
}
var file_v1_syncservice_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_v1_syncservice_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
var file_v1_syncservice_proto_msgTypes = make([]protoimpl.MessageInfo, 15)
var file_v1_syncservice_proto_goTypes = []any{
(SyncConnectionState)(0), // 0: v1.SyncConnectionState
(SyncStreamItem_RepoConnectionState)(0), // 1: v1.SyncStreamItem.RepoConnectionState
(*SyncStateStreamRequest)(nil), // 2: v1.SyncStateStreamRequest
(*PeerState)(nil), // 3: v1.PeerState
(*SyncStreamItem)(nil), // 4: v1.SyncStreamItem
(*RemoteConfig)(nil), // 5: v1.RemoteConfig
(*SyncStreamItem_SyncActionHandshake)(nil), // 6: v1.SyncStreamItem.SyncActionHandshake
(*SyncStreamItem_SyncActionHeartbeat)(nil), // 7: v1.SyncStreamItem.SyncActionHeartbeat
(*SyncStreamItem_SyncActionSendConfig)(nil), // 8: v1.SyncStreamItem.SyncActionSendConfig
(*SyncStreamItem_SyncActionSetConfig)(nil), // 9: v1.SyncStreamItem.SyncActionSetConfig
(*SyncStreamItem_SyncActionListResources)(nil), // 10: v1.SyncStreamItem.SyncActionListResources
(*SyncStreamItem_SyncActionConnectRepo)(nil), // 11: v1.SyncStreamItem.SyncActionConnectRepo
(*SyncStreamItem_SyncActionDiffOperations)(nil), // 12: v1.SyncStreamItem.SyncActionDiffOperations
(*SyncStreamItem_SyncActionSendOperations)(nil), // 13: v1.SyncStreamItem.SyncActionSendOperations
(*SyncStreamItem_SyncActionThrottle)(nil), // 14: v1.SyncStreamItem.SyncActionThrottle
(*SyncStreamItem_SyncEstablishSharedSecret)(nil), // 15: v1.SyncStreamItem.SyncEstablishSharedSecret
(*SignedMessage)(nil), // 16: v1.SignedMessage
(*Repo)(nil), // 17: v1.Repo
(*Plan)(nil), // 18: v1.Plan
(*PublicKey)(nil), // 19: v1.PublicKey
(*OpSelector)(nil), // 20: v1.OpSelector
(*OperationEvent)(nil), // 21: v1.OperationEvent
(*TunnelMessage)(nil), // 2: v1.TunnelMessage
(*SyncStateStreamRequest)(nil), // 3: v1.SyncStateStreamRequest
(*PeerState)(nil), // 4: v1.PeerState
(*SyncStreamItem)(nil), // 5: v1.SyncStreamItem
(*RemoteConfig)(nil), // 6: v1.RemoteConfig
(*SyncStreamItem_SyncActionHandshake)(nil), // 7: v1.SyncStreamItem.SyncActionHandshake
(*SyncStreamItem_SyncActionHeartbeat)(nil), // 8: v1.SyncStreamItem.SyncActionHeartbeat
(*SyncStreamItem_SyncActionSendConfig)(nil), // 9: v1.SyncStreamItem.SyncActionSendConfig
(*SyncStreamItem_SyncActionSetConfig)(nil), // 10: v1.SyncStreamItem.SyncActionSetConfig
(*SyncStreamItem_SyncActionListResources)(nil), // 11: v1.SyncStreamItem.SyncActionListResources
(*SyncStreamItem_SyncActionConnectRepo)(nil), // 12: v1.SyncStreamItem.SyncActionConnectRepo
(*SyncStreamItem_SyncActionDiffOperations)(nil), // 13: v1.SyncStreamItem.SyncActionDiffOperations
(*SyncStreamItem_SyncActionSendOperations)(nil), // 14: v1.SyncStreamItem.SyncActionSendOperations
(*SyncStreamItem_SyncActionThrottle)(nil), // 15: v1.SyncStreamItem.SyncActionThrottle
(*SyncStreamItem_SyncEstablishSharedSecret)(nil), // 16: v1.SyncStreamItem.SyncEstablishSharedSecret
(*anypb.Any)(nil), // 17: google.protobuf.Any
(*SignedMessage)(nil), // 18: v1.SignedMessage
(*Repo)(nil), // 19: v1.Repo
(*Plan)(nil), // 20: v1.Plan
(*PublicKey)(nil), // 21: v1.PublicKey
(*OpSelector)(nil), // 22: v1.OpSelector
(*OperationEvent)(nil), // 23: v1.OperationEvent
}
var file_v1_syncservice_proto_depIdxs = []int32{
0, // 0: v1.PeerState.state:type_name -> v1.SyncConnectionState
5, // 1: v1.PeerState.remote_config:type_name -> v1.RemoteConfig
16, // 2: v1.SyncStreamItem.signed_message:type_name -> v1.SignedMessage
6, // 3: v1.SyncStreamItem.handshake:type_name -> v1.SyncStreamItem.SyncActionHandshake
7, // 4: v1.SyncStreamItem.heartbeat:type_name -> v1.SyncStreamItem.SyncActionHeartbeat
12, // 5: v1.SyncStreamItem.diff_operations:type_name -> v1.SyncStreamItem.SyncActionDiffOperations
13, // 6: v1.SyncStreamItem.send_operations:type_name -> v1.SyncStreamItem.SyncActionSendOperations
8, // 7: v1.SyncStreamItem.send_config:type_name -> v1.SyncStreamItem.SyncActionSendConfig
9, // 8: v1.SyncStreamItem.set_config:type_name -> v1.SyncStreamItem.SyncActionSetConfig
10, // 9: v1.SyncStreamItem.list_resources:type_name -> v1.SyncStreamItem.SyncActionListResources
14, // 10: v1.SyncStreamItem.throttle:type_name -> v1.SyncStreamItem.SyncActionThrottle
17, // 11: v1.RemoteConfig.repos:type_name -> v1.Repo
18, // 12: v1.RemoteConfig.plans:type_name -> v1.Plan
19, // 13: v1.SyncStreamItem.SyncActionHandshake.public_key:type_name -> v1.PublicKey
16, // 14: v1.SyncStreamItem.SyncActionHandshake.instance_id:type_name -> v1.SignedMessage
5, // 15: v1.SyncStreamItem.SyncActionSendConfig.config:type_name -> v1.RemoteConfig
17, // 16: v1.SyncStreamItem.SyncActionSetConfig.repos:type_name -> v1.Repo
18, // 17: v1.SyncStreamItem.SyncActionSetConfig.plans:type_name -> v1.Plan
20, // 18: v1.SyncStreamItem.SyncActionDiffOperations.have_operations_selector:type_name -> v1.OpSelector
21, // 19: v1.SyncStreamItem.SyncActionSendOperations.event:type_name -> v1.OperationEvent
4, // 20: v1.BackrestSyncService.Sync:input_type -> v1.SyncStreamItem
2, // 21: v1.BackrestSyncStateService.GetPeerSyncStatesStream:input_type -> v1.SyncStateStreamRequest
4, // 22: v1.BackrestSyncService.Sync:output_type -> v1.SyncStreamItem
3, // 23: v1.BackrestSyncStateService.GetPeerSyncStatesStream:output_type -> v1.PeerState
22, // [22:24] is the sub-list for method output_type
20, // [20:22] 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
17, // 0: v1.TunnelMessage.any:type_name -> google.protobuf.Any
0, // 1: v1.PeerState.state:type_name -> v1.SyncConnectionState
6, // 2: v1.PeerState.remote_config:type_name -> v1.RemoteConfig
18, // 3: v1.SyncStreamItem.signed_message:type_name -> v1.SignedMessage
7, // 4: v1.SyncStreamItem.handshake:type_name -> v1.SyncStreamItem.SyncActionHandshake
8, // 5: v1.SyncStreamItem.heartbeat:type_name -> v1.SyncStreamItem.SyncActionHeartbeat
13, // 6: v1.SyncStreamItem.diff_operations:type_name -> v1.SyncStreamItem.SyncActionDiffOperations
14, // 7: v1.SyncStreamItem.send_operations:type_name -> v1.SyncStreamItem.SyncActionSendOperations
9, // 8: v1.SyncStreamItem.send_config:type_name -> v1.SyncStreamItem.SyncActionSendConfig
10, // 9: v1.SyncStreamItem.set_config:type_name -> v1.SyncStreamItem.SyncActionSetConfig
11, // 10: v1.SyncStreamItem.list_resources:type_name -> v1.SyncStreamItem.SyncActionListResources
15, // 11: v1.SyncStreamItem.throttle:type_name -> v1.SyncStreamItem.SyncActionThrottle
19, // 12: v1.RemoteConfig.repos:type_name -> v1.Repo
20, // 13: v1.RemoteConfig.plans:type_name -> v1.Plan
21, // 14: v1.SyncStreamItem.SyncActionHandshake.public_key:type_name -> v1.PublicKey
18, // 15: v1.SyncStreamItem.SyncActionHandshake.instance_id:type_name -> v1.SignedMessage
6, // 16: v1.SyncStreamItem.SyncActionSendConfig.config:type_name -> v1.RemoteConfig
19, // 17: v1.SyncStreamItem.SyncActionSetConfig.repos:type_name -> v1.Repo
20, // 18: v1.SyncStreamItem.SyncActionSetConfig.plans:type_name -> v1.Plan
22, // 19: v1.SyncStreamItem.SyncActionDiffOperations.have_operations_selector:type_name -> v1.OpSelector
23, // 20: v1.SyncStreamItem.SyncActionSendOperations.event:type_name -> v1.OperationEvent
2, // 21: v1.TunnelService.Tunnel:input_type -> v1.TunnelMessage
5, // 22: v1.BackrestSyncService.Sync:input_type -> v1.SyncStreamItem
3, // 23: v1.BackrestSyncStateService.GetPeerSyncStatesStream:input_type -> v1.SyncStateStreamRequest
2, // 24: v1.TunnelService.Tunnel:output_type -> v1.TunnelMessage
5, // 25: v1.BackrestSyncService.Sync:output_type -> v1.SyncStreamItem
4, // 26: v1.BackrestSyncStateService.GetPeerSyncStatesStream:output_type -> v1.PeerState
24, // [24:27] is the sub-list for method output_type
21, // [21:24] is the sub-list for method input_type
21, // [21:21] is the sub-list for extension type_name
21, // [21:21] is the sub-list for extension extendee
0, // [0:21] is the sub-list for field type_name
}
func init() { file_v1_syncservice_proto_init() }
@@ -1335,7 +1444,7 @@ func file_v1_syncservice_proto_init() {
file_v1_restic_proto_init()
file_v1_service_proto_init()
file_v1_operations_proto_init()
file_v1_syncservice_proto_msgTypes[2].OneofWrappers = []any{
file_v1_syncservice_proto_msgTypes[3].OneofWrappers = []any{
(*SyncStreamItem_SignedMessage)(nil),
(*SyncStreamItem_Handshake)(nil),
(*SyncStreamItem_Heartbeat)(nil),
@@ -1352,9 +1461,9 @@ func file_v1_syncservice_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_v1_syncservice_proto_rawDesc,
NumEnums: 2,
NumMessages: 14,
NumMessages: 15,
NumExtensions: 0,
NumServices: 2,
NumServices: 3,
},
GoTypes: file_v1_syncservice_proto_goTypes,
DependencyIndexes: file_v1_syncservice_proto_depIdxs,
+100
View File
@@ -18,6 +18,106 @@ import (
// Requires gRPC-Go v1.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
TunnelService_Tunnel_FullMethodName = "/v1.TunnelService/Tunnel"
)
// TunnelServiceClient is the client API for TunnelService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
//
// TunnelService allows inverted communicatons from server to client where the server can initiate requests to the client.
type TunnelServiceClient interface {
Tunnel(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[TunnelMessage, TunnelMessage], error)
}
type tunnelServiceClient struct {
cc grpc.ClientConnInterface
}
func NewTunnelServiceClient(cc grpc.ClientConnInterface) TunnelServiceClient {
return &tunnelServiceClient{cc}
}
func (c *tunnelServiceClient) Tunnel(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[TunnelMessage, TunnelMessage], error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
stream, err := c.cc.NewStream(ctx, &TunnelService_ServiceDesc.Streams[0], TunnelService_Tunnel_FullMethodName, cOpts...)
if err != nil {
return nil, err
}
x := &grpc.GenericClientStream[TunnelMessage, TunnelMessage]{ClientStream: stream}
return x, nil
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type TunnelService_TunnelClient = grpc.BidiStreamingClient[TunnelMessage, TunnelMessage]
// TunnelServiceServer is the server API for TunnelService service.
// All implementations must embed UnimplementedTunnelServiceServer
// for forward compatibility.
//
// TunnelService allows inverted communicatons from server to client where the server can initiate requests to the client.
type TunnelServiceServer interface {
Tunnel(grpc.BidiStreamingServer[TunnelMessage, TunnelMessage]) error
mustEmbedUnimplementedTunnelServiceServer()
}
// UnimplementedTunnelServiceServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedTunnelServiceServer struct{}
func (UnimplementedTunnelServiceServer) Tunnel(grpc.BidiStreamingServer[TunnelMessage, TunnelMessage]) error {
return status.Errorf(codes.Unimplemented, "method Tunnel not implemented")
}
func (UnimplementedTunnelServiceServer) mustEmbedUnimplementedTunnelServiceServer() {}
func (UnimplementedTunnelServiceServer) testEmbeddedByValue() {}
// UnsafeTunnelServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to TunnelServiceServer will
// result in compilation errors.
type UnsafeTunnelServiceServer interface {
mustEmbedUnimplementedTunnelServiceServer()
}
func RegisterTunnelServiceServer(s grpc.ServiceRegistrar, srv TunnelServiceServer) {
// If the following call pancis, it indicates UnimplementedTunnelServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&TunnelService_ServiceDesc, srv)
}
func _TunnelService_Tunnel_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(TunnelServiceServer).Tunnel(&grpc.GenericServerStream[TunnelMessage, TunnelMessage]{ServerStream: stream})
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type TunnelService_TunnelServer = grpc.BidiStreamingServer[TunnelMessage, TunnelMessage]
// TunnelService_ServiceDesc is the grpc.ServiceDesc for TunnelService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var TunnelService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "v1.TunnelService",
HandlerType: (*TunnelServiceServer)(nil),
Methods: []grpc.MethodDesc{},
Streams: []grpc.StreamDesc{
{
StreamName: "Tunnel",
Handler: _TunnelService_Tunnel_Handler,
ServerStreams: true,
ClientStreams: true,
},
},
Metadata: "v1/syncservice.proto",
}
const (
BackrestSyncService_Sync_FullMethodName = "/v1.BackrestSyncService/Sync"
)
@@ -21,6 +21,8 @@ import (
const _ = connect.IsAtLeastVersion1_13_0
const (
// TunnelServiceName is the fully-qualified name of the TunnelService service.
TunnelServiceName = "v1.TunnelService"
// BackrestSyncServiceName is the fully-qualified name of the BackrestSyncService service.
BackrestSyncServiceName = "v1.BackrestSyncService"
// BackrestSyncStateServiceName is the fully-qualified name of the BackrestSyncStateService service.
@@ -35,6 +37,8 @@ const (
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
// period.
const (
// TunnelServiceTunnelProcedure is the fully-qualified name of the TunnelService's Tunnel RPC.
TunnelServiceTunnelProcedure = "/v1.TunnelService/Tunnel"
// BackrestSyncServiceSyncProcedure is the fully-qualified name of the BackrestSyncService's Sync
// RPC.
BackrestSyncServiceSyncProcedure = "/v1.BackrestSyncService/Sync"
@@ -45,12 +49,82 @@ const (
// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package.
var (
tunnelServiceServiceDescriptor = v1.File_v1_syncservice_proto.Services().ByName("TunnelService")
tunnelServiceTunnelMethodDescriptor = tunnelServiceServiceDescriptor.Methods().ByName("Tunnel")
backrestSyncServiceServiceDescriptor = v1.File_v1_syncservice_proto.Services().ByName("BackrestSyncService")
backrestSyncServiceSyncMethodDescriptor = backrestSyncServiceServiceDescriptor.Methods().ByName("Sync")
backrestSyncStateServiceServiceDescriptor = v1.File_v1_syncservice_proto.Services().ByName("BackrestSyncStateService")
backrestSyncStateServiceGetPeerSyncStatesStreamMethodDescriptor = backrestSyncStateServiceServiceDescriptor.Methods().ByName("GetPeerSyncStatesStream")
)
// TunnelServiceClient is a client for the v1.TunnelService service.
type TunnelServiceClient interface {
Tunnel(context.Context) *connect.BidiStreamForClient[v1.TunnelMessage, v1.TunnelMessage]
}
// NewTunnelServiceClient constructs a client for the v1.TunnelService service. By default, it uses
// the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends
// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or
// connect.WithGRPCWeb() options.
//
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
// http://api.acme.com or https://acme.com/grpc).
func NewTunnelServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) TunnelServiceClient {
baseURL = strings.TrimRight(baseURL, "/")
return &tunnelServiceClient{
tunnel: connect.NewClient[v1.TunnelMessage, v1.TunnelMessage](
httpClient,
baseURL+TunnelServiceTunnelProcedure,
connect.WithSchema(tunnelServiceTunnelMethodDescriptor),
connect.WithClientOptions(opts...),
),
}
}
// tunnelServiceClient implements TunnelServiceClient.
type tunnelServiceClient struct {
tunnel *connect.Client[v1.TunnelMessage, v1.TunnelMessage]
}
// Tunnel calls v1.TunnelService.Tunnel.
func (c *tunnelServiceClient) Tunnel(ctx context.Context) *connect.BidiStreamForClient[v1.TunnelMessage, v1.TunnelMessage] {
return c.tunnel.CallBidiStream(ctx)
}
// TunnelServiceHandler is an implementation of the v1.TunnelService service.
type TunnelServiceHandler interface {
Tunnel(context.Context, *connect.BidiStream[v1.TunnelMessage, v1.TunnelMessage]) error
}
// NewTunnelServiceHandler builds an HTTP handler from the service implementation. It returns the
// path on which to mount the handler and the handler itself.
//
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
// and JSON codecs. They also support gzip compression.
func NewTunnelServiceHandler(svc TunnelServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
tunnelServiceTunnelHandler := connect.NewBidiStreamHandler(
TunnelServiceTunnelProcedure,
svc.Tunnel,
connect.WithSchema(tunnelServiceTunnelMethodDescriptor),
connect.WithHandlerOptions(opts...),
)
return "/v1.TunnelService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case TunnelServiceTunnelProcedure:
tunnelServiceTunnelHandler.ServeHTTP(w, r)
default:
http.NotFound(w, r)
}
})
}
// UnimplementedTunnelServiceHandler returns CodeUnimplemented from all methods.
type UnimplementedTunnelServiceHandler struct{}
func (UnimplementedTunnelServiceHandler) Tunnel(context.Context, *connect.BidiStream[v1.TunnelMessage, v1.TunnelMessage]) error {
return connect.NewError(connect.CodeUnimplemented, errors.New("v1.TunnelService.Tunnel is not implemented"))
}
// BackrestSyncServiceClient is a client for the v1.BackrestSyncService service.
type BackrestSyncServiceClient interface {
Sync(context.Context) *connect.BidiStreamForClient[v1.SyncStreamItem, v1.SyncStreamItem]
+10 -29
View File
@@ -4,7 +4,6 @@ import (
"context"
"errors"
"fmt"
"net"
"net/http"
"path/filepath"
"slices"
@@ -74,8 +73,8 @@ func TestConnectionSucceeds(t *testing.T) {
testutil.InstallZapLogger(t)
ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
peerHostAddr := allocBindAddrForTest(t)
peerClientAddr := allocBindAddrForTest(t)
peerHostAddr := testutil.AllocOpenBindAddr(t)
peerClientAddr := testutil.AllocOpenBindAddr(t)
peerHostConfig := &v1.Config{
Instance: defaultHostID,
@@ -120,8 +119,8 @@ func TestConnectionBadKeyRejected(t *testing.T) {
testutil.InstallZapLogger(t)
ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
peerHostAddr := allocBindAddrForTest(t)
peerClientAddr := allocBindAddrForTest(t)
peerHostAddr := testutil.AllocOpenBindAddr(t)
peerClientAddr := testutil.AllocOpenBindAddr(t)
// Host has identity1, and authorizes no one.
peerHostConfig := &v1.Config{
@@ -162,8 +161,8 @@ func TestSyncConfigChange(t *testing.T) {
testutil.InstallZapLogger(t)
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
peerHostAddr := allocBindAddrForTest(t)
peerClientAddr := allocBindAddrForTest(t)
peerHostAddr := testutil.AllocOpenBindAddr(t)
peerClientAddr := testutil.AllocOpenBindAddr(t)
peerHostConfig := &v1.Config{
Instance: defaultHostID,
@@ -254,8 +253,8 @@ func TestSimpleOperationSync(t *testing.T) {
testutil.InstallZapLogger(t)
ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
peerHostAddr := allocBindAddrForTest(t)
peerClientAddr := allocBindAddrForTest(t)
peerHostAddr := testutil.AllocOpenBindAddr(t)
peerClientAddr := testutil.AllocOpenBindAddr(t)
peerHostConfig := &v1.Config{
Instance: defaultHostID,
@@ -378,8 +377,8 @@ func TestSyncMutations(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
peerHostAddr := allocBindAddrForTest(t)
peerClientAddr := allocBindAddrForTest(t)
peerHostAddr := testutil.AllocOpenBindAddr(t)
peerClientAddr := testutil.AllocOpenBindAddr(t)
peerHostConfig := &v1.Config{
Instance: defaultHostID,
@@ -658,24 +657,6 @@ func tryConnect(t *testing.T, ctx context.Context, peer *peerUnderTest, hostPeer
waitForConnectionState(t, ctx, peer, hostPeer, v1.SyncConnectionState_CONNECTION_STATE_CONNECTED)
}
func allocBindAddrForTest(t *testing.T) string {
t.Helper()
listener, err := net.Listen("tcp", ":0")
if err != nil {
t.Fatalf("failed to listen: %v", err)
}
defer listener.Close()
// Get the port number from the listener
_, port, err := net.SplitHostPort(listener.Addr().String())
if err != nil {
t.Fatalf("failed to split host and port: %v", err)
}
return "127.0.0.1:" + port
}
func runSyncAPIWithCtx(ctx context.Context, peer *peerUnderTest, bindAddr string) {
mux := http.NewServeMux()
syncHandler := NewBackrestSyncHandler(peer.manager)
+205
View File
@@ -0,0 +1,205 @@
package tunnel
import (
"fmt"
"net"
"os"
"sync"
"sync/atomic"
"time"
v1 "github.com/garethgeorge/backrest/gen/go/v1"
"go.uber.org/zap"
)
type connState struct {
connId int64
nextWriteSeqno int64
stream stream // stream it's associated with
logger *zap.Logger // can be nil
closed atomic.Bool
closedCh chan struct{}
sendMu sync.Mutex
seqno int64
readsMu sync.Mutex
reads chan []byte
readsBuf []byte
readDeadlineMu sync.Mutex
readDeadlineTimer *time.Timer
readDeadlineChan chan struct{}
}
var _ net.Conn = (*connState)(nil)
func newConnState(stream stream, connId int64, logger *zap.Logger) *connState {
if logger != nil {
logger = logger.Named("connState").With(
zap.Int64("connId", connId))
}
return &connState{
connId: connId,
seqno: 0,
stream: stream,
logger: logger,
closedCh: make(chan struct{}),
reads: make(chan []byte, 10), // Buffered channel to hold a few writes worth of messages before blocking
readsBuf: nil,
readDeadlineChan: make(chan struct{}),
}
}
// sendOpenPacket is only sent by the end starting the connection, not by the end that's opening it in response to a receive.
func (c *connState) sendOpenPacket() error {
if c.closed.Load() {
return net.ErrClosed
}
if c.logger != nil {
c.logger.Info("sending open packet")
}
return c.stream.Send(&v1.TunnelMessage{
ConnId: c.connId,
Seqno: 0, // Open packet has Seqno 0
})
}
func (c *connState) Write(data []byte) (int, error) {
c.sendMu.Lock()
defer c.sendMu.Unlock()
if c.closed.Load() {
return 0, net.ErrClosed
}
c.seqno++
if c.logger != nil {
c.logger.Debug("writing data", zap.Int("dataLength", len(data)), zap.Int64("seqno", c.seqno))
}
err := c.stream.Send(&v1.TunnelMessage{
ConnId: c.connId,
Data: data,
Seqno: c.nextWriteSeqno,
})
if err != nil {
if c.logger != nil {
c.logger.Error("failed to send data", zap.Int64("connId", c.connId), zap.Error(err))
}
return 0, err
}
return len(data), nil
}
func (c *connState) Read(b []byte) (int, error) {
c.readsMu.Lock()
defer c.readsMu.Unlock()
if len(c.readsBuf) > 0 {
n := copy(b, c.readsBuf)
c.readsBuf = c.readsBuf[n:]
return n, nil
}
c.readDeadlineMu.Lock()
readDeadlineChan := c.readDeadlineChan
c.readDeadlineMu.Unlock()
select {
case data := <-c.reads:
if len(data) == 0 {
return 0, net.ErrClosed
}
if c.logger != nil {
c.logger.Debug("conn state c.reads received packet", zap.Int("dataLength", len(data)))
}
n := copy(b, data)
if n < len(data) {
c.readsBuf = data[n:]
}
return n, nil
case <-readDeadlineChan:
if c.logger != nil {
c.logger.Info("read deadline reached")
}
return 0, os.ErrDeadlineExceeded
case <-c.closedCh:
if c.logger != nil {
c.logger.Info("connection closed while waiting for read")
}
return 0, net.ErrClosed
}
}
func (c *connState) Close() error {
if !c.closed.Swap(true) {
if c.logger != nil {
c.logger.Info("closing connection")
}
close(c.closedCh)
if err := c.stream.Send(&v1.TunnelMessage{
ConnId: c.connId,
Close: true,
}); err != nil {
if c.logger != nil {
c.logger.Error("failed to send close message", zap.Error(err))
}
return fmt.Errorf("send close message: %w", err)
}
if c.logger != nil {
c.logger.Info("connection closed successfully")
}
} else if c.logger != nil {
c.logger.Warn("close called on already closed connection")
}
return nil
}
func (c *connState) LocalAddr() net.Addr {
// Return the local address of the tunnel connection
return &net.TCPAddr{
IP: net.IPv4zero,
Port: 0,
}
}
func (c *connState) RemoteAddr() net.Addr {
// Return the remote address of the tunnel connection
return &net.TCPAddr{
IP: net.IPv4zero,
Port: 0,
}
}
func (c *connState) SetDeadline(t time.Time) error {
c.SetReadDeadline(t)
c.SetWriteDeadline(t)
return nil
}
func (c *connState) SetReadDeadline(t time.Time) error {
c.readDeadlineMu.Lock()
defer c.readDeadlineMu.Unlock()
if c.readDeadlineTimer != nil {
c.readDeadlineTimer.Stop()
}
if t.IsZero() {
c.readDeadlineTimer = nil
return nil
}
c.readDeadlineTimer = time.AfterFunc(time.Until(t), func() {
close(c.readDeadlineChan)
})
c.readDeadlineChan = make(chan struct{}) // Reset the channel to ensure it is ready for the next deadline
return nil
}
func (c *connState) SetWriteDeadline(t time.Time) error {
// TODO: simply does not work right now
return nil
}
+27
View File
@@ -0,0 +1,27 @@
package tunnel
import (
"crypto/tls"
"net"
"net/http"
"time"
"go.uber.org/zap"
"golang.org/x/net/http2"
)
// NewInsecureHttpClient creates a new HTTP client that allows insecure connections (HTTP/2 over plain TCP).
// This is useful for testing or when you don't need TLS.
func NewInsecureHttpClient() *http.Client {
return &http.Client{
Transport: &http2.Transport{
AllowHTTP: true,
DialTLS: func(network, addr string, _ *tls.Config) (net.Conn, error) {
zap.L().Sugar().Debugf("Dialing %s on %s", network, addr)
return net.Dial(network, addr)
},
IdleConnTimeout: 300 * time.Second,
ReadIdleTimeout: 60 * time.Second,
},
}
}
+59
View File
@@ -0,0 +1,59 @@
package tunnel
import (
"net"
"sync"
)
// tunnelListener is a net.Listener that makes it possible to feed net.Conn instances into it.
type ConnectionProvider struct {
doClose sync.Once
isOpen chan struct{}
nextConn chan net.Conn
}
var _ net.Listener = (*ConnectionProvider)(nil)
func NewConnectionProvider(bufferSize int) *ConnectionProvider {
return &ConnectionProvider{
isOpen: make(chan struct{}),
nextConn: make(chan net.Conn, bufferSize), // Buffered channel to hold incoming connections
}
}
var _ net.Listener = (*ConnectionProvider)(nil)
func (l *ConnectionProvider) Accept() (net.Conn, error) {
select {
case <-l.isOpen:
// If the listener is closed, we don't accept new connections.
return nil, &net.OpError{Op: "accept", Net: "tunnel", Err: net.ErrClosed}
case conn := <-l.nextConn:
return conn, nil
}
}
func (l *ConnectionProvider) Close() error {
l.doClose.Do(func() {
close(l.isOpen) // Close the channel to signal that the listener is closed
})
return nil
}
func (l *ConnectionProvider) Addr() net.Addr {
return &net.TCPAddr{
IP: net.IPv4zero,
Port: 0, // Port is not used in this implementation
}
}
func (l *ConnectionProvider) ProvideConn(conn net.Conn) {
select {
case <-l.isOpen:
// If the listener is closed, we don't accept new connections.
conn.Close()
return
case l.nextConn <- conn:
// Successfully provided the connection
}
}
+94
View File
@@ -0,0 +1,94 @@
package tunnel
import (
"errors"
"sync"
"sync/atomic"
"connectrpc.com/connect"
v1 "github.com/garethgeorge/backrest/gen/go/v1"
"github.com/hashicorp/go-multierror"
)
var ErrStreamClosed = errors.New("stream closed")
type stream interface {
Send(item *v1.TunnelMessage) error
Receive() (*v1.TunnelMessage, error)
Close() error
}
type clientStream struct {
sendMu sync.Mutex
receiveMu sync.Mutex
stream *connect.BidiStreamForClient[v1.TunnelMessage, v1.TunnelMessage]
closed atomic.Bool
}
func (s *clientStream) Send(item *v1.TunnelMessage) error {
s.sendMu.Lock()
defer s.sendMu.Unlock()
if s.closed.Load() {
return connect.NewError(connect.CodeFailedPrecondition, ErrStreamClosed)
}
return s.stream.Send(item)
}
func (s *clientStream) Receive() (*v1.TunnelMessage, error) {
s.receiveMu.Lock()
defer s.receiveMu.Unlock()
if s.closed.Load() {
return nil, connect.NewError(connect.CodeFailedPrecondition, ErrStreamClosed)
}
return s.stream.Receive()
}
// Close closes the request side of the stream, allowing the server to finish processing.
// It will block if Receive or Send are in progress.
func (s *clientStream) Close() error {
s.closed.Store(true)
s.receiveMu.Lock()
var err error
if e := s.stream.CloseResponse(); e != nil {
err = multierror.Append(err, e)
}
s.receiveMu.Unlock()
s.sendMu.Lock()
if e := s.stream.CloseRequest(); e != nil {
err = multierror.Append(err, e)
}
s.sendMu.Unlock()
return err
}
type serverStream struct {
sendMu sync.Mutex
receiveMu sync.Mutex
stream *connect.BidiStream[v1.TunnelMessage, v1.TunnelMessage]
closed atomic.Bool
}
func (s *serverStream) Send(item *v1.TunnelMessage) error {
s.sendMu.Lock()
defer s.sendMu.Unlock()
if s.closed.Load() {
return connect.NewError(connect.CodeFailedPrecondition, ErrStreamClosed)
}
return s.stream.Send(item)
}
func (s *serverStream) Receive() (*v1.TunnelMessage, error) {
s.receiveMu.Lock()
defer s.receiveMu.Unlock()
if s.closed.Load() {
return nil, connect.NewError(connect.CodeFailedPrecondition, ErrStreamClosed)
}
return s.stream.Receive()
}
func (s *serverStream) Close() error {
s.receiveMu.Lock()
s.sendMu.Lock()
s.closed.Store(true)
return nil
}
+176
View File
@@ -0,0 +1,176 @@
package tunnel
import (
"bufio"
"context"
"io"
"net"
"net/http"
"testing"
"time"
"connectrpc.com/connect"
v1 "github.com/garethgeorge/backrest/gen/go/v1"
"github.com/garethgeorge/backrest/gen/go/v1/v1connect"
"github.com/garethgeorge/backrest/internal/testutil"
"go.uber.org/zap"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
)
func newHelloHandler() http.Handler {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("Hello, World!"))
})
return mux
}
type sampleHandler struct {
logger *zap.Logger
streams []*WrappedStream
provider *ConnectionProvider
}
var _ v1connect.TunnelServiceHandler = (*sampleHandler)(nil)
func (sh *sampleHandler) Tunnel(ctx context.Context, stream *connect.BidiStream[v1.TunnelMessage, v1.TunnelMessage]) error {
wrapped := NewWrappedStream(stream, WithLogger(sh.logger))
wrapped.ProvideConnectionsTo(sh.provider)
sh.streams = append(sh.streams, wrapped)
return wrapped.HandlePackets(ctx)
}
func serveForTest(name string, t *testing.T, server *http.Server, listener net.Listener) {
t.Helper()
go func() {
t.Logf("Starting server %s with listener", name)
if err := server.Serve(listener); err != nil && err != http.ErrServerClosed {
t.Errorf("Server %s failed to start: %v", name, err)
}
}()
t.Cleanup(func() {
t.Logf("Shutting down server %s", name)
deadline, cancel := context.WithDeadline(context.Background(), time.Now().Add(2*time.Second))
defer cancel()
if err := server.Shutdown(deadline); err != nil {
t.Errorf("Failed to close server %s: %v", name, err)
} else {
t.Logf("Server %s closed successfully", name)
}
})
}
func listenAndServeForTest(name string, t *testing.T, server *http.Server) {
t.Helper()
go func() {
t.Logf("Starting server %s on %s", name, server.Addr)
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
t.Errorf("Server %s failed to start: %v", name, err)
} else {
t.Logf("Server %s closed successfully", name)
}
}()
t.Cleanup(func() {
t.Logf("Shutting down server %s on %s", name, server.Addr)
if err := server.Shutdown(context.Background()); err != nil {
t.Errorf("Failed to close server %s: %v", name, err)
}
})
}
func waitForConnectionReady(ctx context.Context, t *testing.T, wrapped *WrappedStream) {
for {
select {
case <-ctx.Done():
t.Fatalf("timed out waiting for connection to be ready: %v", ctx.Err())
default:
if wrapped.IsReady() {
return
}
time.Sleep(10 * time.Millisecond)
}
}
}
func TestConnect(t *testing.T) {
ctx, cancel := testutil.WithDeadlineFromTest(t, context.Background())
defer cancel()
// Construct the service we want to provide
provider := NewConnectionProvider(10 /* bufferSize */)
sampleHandler := &sampleHandler{
logger: testutil.NewTestLogger(t).Named("sample-handler"),
provider: provider,
}
server := &http.Server{
Handler: newHelloHandler(),
}
serveForTest("HTTPServer", t, server, provider)
// Serve the sample handler
mux := http.NewServeMux()
mux.Handle(v1connect.NewTunnelServiceHandler(sampleHandler))
grpcServer := &http.Server{
Addr: testutil.AllocOpenBindAddr(t),
Handler: h2c.NewHandler(mux, &http2.Server{}), // h2c is HTTP/2 without TLS for grpc-connect support.
}
listenAndServeForTest("gRPCServer", t, grpcServer)
// Create a client and connect to the server
client := v1connect.NewTunnelServiceClient(NewInsecureHttpClient(), "http://"+grpcServer.Addr)
stream := client.Tunnel(ctx)
wrapped := NewWrappedStreamFromClient(stream, WithLogger(testutil.NewTestLogger(t).Named("client")))
go func() {
t.Log("Client stream started")
if err := wrapped.HandlePackets(ctx); err != nil {
t.Errorf("Failed to handle packets: %v", err)
}
t.Log("Client stream ended")
}()
waitForConnectionReady(ctx, t, wrapped)
// Attempt to connect to the server
conn, err := wrapped.Dial()
if err != nil {
t.Fatalf("Failed to dial server: %v", err)
}
// Write an HTTP request to the connection
req, err := http.NewRequest("GET", "http://example.com", nil)
if err != nil {
t.Fatalf("Failed to create request: %v", err)
}
if err := req.Write(conn); err != nil {
t.Fatalf("Failed to write request: %v", err)
}
// Read the response
resp, err := http.ReadResponse(bufio.NewReader(conn), req)
if err != nil {
t.Fatalf("Failed to read response: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Fatalf("Expected status OK, got %s", resp.Status)
}
t.Logf("Received response: %s", resp.Status)
body, err := io.ReadAll(resp.Body)
if err != nil {
t.Fatalf("Failed to read response body: %v", err)
}
t.Logf("Response body: %s", body)
t.Logf("Closing connection with ID %d", conn.(*connState).connId)
if err := conn.Close(); err != nil {
t.Fatalf("Failed to close connection: %v", err)
}
t.Logf("Calling wrapped.Shutdown()")
if err := wrapped.Shutdown(); err != nil {
t.Fatalf("Failed to shutdown wrapped stream: %v", err)
}
t.Log("Test completed successfully")
}
@@ -0,0 +1,290 @@
package tunnel
import (
"context"
"crypto/ecdh"
"crypto/rand"
"fmt"
"net"
"sync"
"sync/atomic"
"time"
"connectrpc.com/connect"
v1 "github.com/garethgeorge/backrest/gen/go/v1"
"go.uber.org/zap"
)
type WrappedStreamOptions func(*WrappedStream)
func WithLogger(logger *zap.Logger) WrappedStreamOptions {
return func(ws *WrappedStream) {
ws.logger = logger
}
}
func WithHeartbeatInterval(interval time.Duration) WrappedStreamOptions {
return func(ws *WrappedStream) {
ws.heartbeatInterval = interval
}
}
type WrappedStream struct {
isClient bool
stream stream
logger *zap.Logger
provider *ConnectionProvider // is nil until ProvideConnectionsTo is called
heartbeatInterval time.Duration // interval for heartbeat messages, if set
// pool of connections, every connection is bidirectional so can be initiated from either side.
connsMu sync.Mutex
conns map[int64]*connState
lastConnID atomic.Int64
handlingPackets atomic.Bool
streamStopped atomic.Bool
}
func newWrappedStreamInternal(stream stream, isClient bool, opts ...WrappedStreamOptions) *WrappedStream {
ws := &WrappedStream{
isClient: isClient,
stream: stream,
heartbeatInterval: 30 * time.Second,
conns: make(map[int64]*connState),
}
for _, opt := range opts {
opt(ws)
}
if isClient {
ws.lastConnID.Store(1) // Use odd numbered connection IDs for client-initiated connections.
} else {
ws.lastConnID.Store(2) // Use even numbered connection IDs for server-initiated connections.
}
return ws
}
func NewWrappedStream(stream *connect.BidiStream[v1.TunnelMessage, v1.TunnelMessage], opts ...WrappedStreamOptions) *WrappedStream {
return newWrappedStreamInternal(&serverStream{
stream: stream,
}, false, opts...)
}
func NewWrappedStreamFromClient(stream *connect.BidiStreamForClient[v1.TunnelMessage, v1.TunnelMessage], opts ...WrappedStreamOptions) *WrappedStream {
return newWrappedStreamInternal(&clientStream{
stream: stream,
}, true, opts...)
}
func (ws *WrappedStream) allocConnID() int64 {
return ws.lastConnID.Add(2)
}
func (ws *WrappedStream) IsReady() bool {
return ws.handlingPackets.Load() && !ws.streamStopped.Load()
}
func (ws *WrappedStream) Dial() (net.Conn, error) {
if !ws.handlingPackets.Load() {
return nil, fmt.Errorf("cannot dial before handling packets")
}
connID := ws.allocConnID()
new := newConnState(ws.stream, connID, ws.logger)
if err := new.sendOpenPacket(); err != nil {
return nil, fmt.Errorf("send open packet: %w", err)
}
ws.connsMu.Lock()
defer ws.connsMu.Unlock()
ws.conns[connID] = new
return new, nil
}
func (ws *WrappedStream) ProvideConnectionsTo(provider *ConnectionProvider) {
ws.provider = provider
}
func (ws *WrappedStream) sendHeartbeats(ctx context.Context) {
if ws.heartbeatInterval <= 0 || !ws.isClient {
return
}
ticker := time.NewTicker(ws.heartbeatInterval)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
if ws.logger != nil {
ws.logger.Debug("sending heartbeat")
}
if err := ws.stream.Send(&v1.TunnelMessage{
ConnId: -1, // handshake packet
}); err != nil && ws.logger != nil {
ws.logger.Error("failed to send heartbeat", zap.Error(err))
}
}
}
}
func (ws *WrappedStream) HandlePackets(ctx context.Context) error {
if ws.handlingPackets.Swap(true) {
return fmt.Errorf("already handling packets")
}
defer ws.handlingPackets.Store(false)
if ws.streamStopped.Load() {
return fmt.Errorf("stream already stopped")
}
// TODO: optimization, it is generally secure and performant have a singleton key that is generated once and reused for all connections.
// the only risk w/this approach is if the key were somehow leaked all related connections would be compromised. The risk is low in this case since
// the key is only kept in memory for the lifetime of the process, and ideally is a second line of defense after TLS.
key, err := ecdh.X25519().GenerateKey(rand.Reader)
if err != nil {
return fmt.Errorf("generate key for handshake packet: %w", err)
}
if err := ws.stream.Send(&v1.TunnelMessage{
ConnId: -100, // hadnshake packet
PubkeyEcdhX25519: key.PublicKey().Bytes(),
}); err != nil {
return fmt.Errorf("send handshake packet: %w", err)
}
// receive handshake packet
handshake, err := ws.stream.Receive()
if err != nil {
return fmt.Errorf("receive handshake packet: %w", err)
}
if handshake.GetConnId() != -100 {
return fmt.Errorf("expected handshake packet with connId -100, got %d", handshake.GetConnId())
}
if len(handshake.PubkeyEcdhX25519) == 0 {
return fmt.Errorf("handshake packet does not contain public key")
}
peerKey, err := ecdh.X25519().NewPublicKey(handshake.PubkeyEcdhX25519)
if err != nil {
return fmt.Errorf("parse peer public key: %w", err)
}
_, err = key.ECDH(peerKey)
if err != nil {
return fmt.Errorf("compute shared key: %w", err)
}
// TODO: use the key for encryption and decryption of messages.
newConn := func(connId int64) *connState {
if ws.logger != nil {
ws.logger.Info("new tunnel connection", zap.Int64("connId", connId))
}
new := newConnState(ws.stream, connId, ws.logger)
ws.conns[connId] = new
ws.provider.ProvideConn(new)
return new
}
headOfLineBlockingTimer := time.NewTimer(0)
defer headOfLineBlockingTimer.Stop()
// send heartbeats in a separate goroutine if heartbeat interval is set
go ws.sendHeartbeats(ctx)
for {
msg, err := ws.stream.Receive()
if err != nil {
if ws.handlingPackets.Load() {
return nil
}
return fmt.Errorf("receive message: %w", err)
}
connId := msg.GetConnId()
if connId <= 0 {
// negative IDs are reserved for healthchecks and control messages, ignored.
continue
}
if msg.Close {
if ws.logger != nil {
ws.logger.Info("closing connection", zap.Int64("connId", connId))
}
ws.connsMu.Lock()
if conn, exists := ws.conns[connId]; exists {
if err := conn.Close(); err != nil && ws.logger != nil {
ws.logger.Error("failed to close connection", zap.Int64("connId", connId), zap.Error(err))
}
delete(ws.conns, connId)
}
ws.connsMu.Unlock()
continue
}
ws.connsMu.Lock()
conn, exists := ws.conns[connId]
if !exists {
if msg.Seqno != 0 {
if ws.logger != nil {
ws.logger.Warn("received message for unknown connection", zap.Int64("connId", connId), zap.Int64("seqno", msg.Seqno))
}
continue
}
if ws.provider == nil {
if ws.logger != nil {
ws.logger.Warn("received open packet for unknown connection, but no provider is set, ignoring the connection", zap.Int64("connId", connId))
}
continue
}
conn = newConn(connId)
}
ws.connsMu.Unlock()
if len(msg.Data) == 0 {
continue
}
headOfLineBlockingTimer.Reset(100 * time.Millisecond)
select {
case <-conn.closedCh:
if ws.logger != nil {
ws.logger.Warn("received message for closed connection", zap.Int64("connId", connId), zap.Int64("seqno", msg.Seqno))
}
case conn.reads <- msg.Data:
if ws.logger != nil {
ws.logger.Debug("received data on tunnel connection", zap.Int64("connId", connId), zap.Int64("seqno", msg.Seqno), zap.Int("dataLength", len(msg.Data)))
}
case <-headOfLineBlockingTimer.C:
if ws.logger != nil {
ws.logger.Warn("head-of-line blocking detected, no reads available for connection", zap.Int64("connId", connId), zap.Int64("seqno", msg.Seqno))
}
conn.Close()
case <-ctx.Done():
// Close all open connections when the context is done.
ws.connsMu.Lock()
if ws.logger != nil {
ws.logger.Info("context done, closing all connections")
}
for _, c := range ws.conns {
if err := c.Close(); err != nil && ws.logger != nil {
ws.logger.Error("failed to close connection on context done", zap.Int64("connId", c.connId), zap.Error(err))
}
}
ws.connsMu.Unlock()
return nil
}
}
}
func (ws *WrappedStream) Shutdown() error {
if ws.streamStopped.Swap(true) {
if ws.logger != nil {
ws.logger.Warn("wrapped stream already shutdown")
}
return nil
}
return ws.stream.Close()
}
-1
View File
@@ -17,7 +17,6 @@ import (
var (
curve = elliptic.P256() // ed25519
)
type PublicKey struct {
+9 -3
View File
@@ -13,16 +13,22 @@ type testLogger struct {
}
func (l *testLogger) Write(p []byte) (n int, err error) {
l.t.Log("global log: " + strings.Trim(string(p), "\n"))
l.t.Log(strings.Trim(string(p), "\n"))
return len(p), nil
}
// InstallZapLogger sets up a global zap logger for testing purposes.
func InstallZapLogger(t *testing.T) {
t.Helper()
logger := zap.New(zapcore.NewCore(
zap.ReplaceGlobals(NewTestLogger(t))
}
// NewTestLogger creates a zap logger for testing that outputs to the test log.
func NewTestLogger(t *testing.T) *zap.Logger {
t.Helper()
return zap.New(zapcore.NewCore(
zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()),
zapcore.AddSync(&testLogger{t: t}),
zapcore.DebugLevel,
))
zap.ReplaceGlobals(logger)
}
+18
View File
@@ -12,6 +12,24 @@ import "v1/operations.proto";
import "types/value.proto";
import "google/protobuf/empty.proto";
import "google/api/annotations.proto";
import "google/protobuf/any.proto";
// TunnelService allows inverted communicatons from server to client where the server can initiate requests to the client.
service TunnelService {
rpc Tunnel(stream TunnelMessage) returns (stream TunnelMessage) {}
}
message TunnelMessage {
int64 conn_id = 1; // The connection ID this request belongs to, enables multiplexing.
int64 seqno = 2;
bytes data = 3; // The data to send, this is a raw byte stream.
bool close = 4; // If true, the write end should be closed after this request.
bytes pubkey_ecdh_x25519 = 100; // The public key used for ECDH key exchange, binary encoded.
google.protobuf.Any any = 1000; // Available to allow sending custom data down the tunnel in the initial handshake.
}
// BackrestSyncService provides methods to sync data between backrest instances.
+89 -19
View File
@@ -14,7 +14,8 @@ import { file_v1_service } from "./service_pb";
import type { OperationEvent } from "./operations_pb";
import { file_v1_operations } from "./operations_pb";
import { file_types_value } from "../types/value_pb";
import { file_google_protobuf_empty } from "@bufbuild/protobuf/wkt";
import type { Any } from "@bufbuild/protobuf/wkt";
import { file_google_protobuf_any, file_google_protobuf_empty } from "@bufbuild/protobuf/wkt";
import { file_google_api_annotations } from "../google/api/annotations_pb";
import type { Message } from "@bufbuild/protobuf";
@@ -22,7 +23,59 @@ import type { Message } from "@bufbuild/protobuf";
* Describes the file v1/syncservice.proto.
*/
export const file_v1_syncservice: GenFile = /*@__PURE__*/
fileDesc("ChR2MS9zeW5jc2VydmljZS5wcm90bxICdjEiKwoWU3luY1N0YXRlU3RyZWFtUmVxdWVzdBIRCglzdWJzY3JpYmUYASABKAgi6wEKCVBlZXJTdGF0ZRIYChBwZWVyX2luc3RhbmNlX2lkGAEgASgJEhIKCnBlZXJfa2V5aWQYAiABKAkSJgoFc3RhdGUYAyABKA4yFy52MS5TeW5jQ29ubmVjdGlvblN0YXRlEhYKDnN0YXR1c19tZXNzYWdlGAQgASgJEhMKC2tub3duX3BsYW5zGAUgAygJEhMKC2tub3duX3JlcG9zGAYgAygJEicKDXJlbW90ZV9jb25maWcYByABKAsyEC52MS5SZW1vdGVDb25maWcSHQoVbGFzdF9oZWFydGJlYXRfbWlsbGlzGAggASgDIoAMCg5TeW5jU3RyZWFtSXRlbRIrCg5zaWduZWRfbWVzc2FnZRgBIAEoCzIRLnYxLlNpZ25lZE1lc3NhZ2VIABI7CgloYW5kc2hha2UYAyABKAsyJi52MS5TeW5jU3RyZWFtSXRlbS5TeW5jQWN0aW9uSGFuZHNoYWtlSAASOwoJaGVhcnRiZWF0GAQgASgLMiYudjEuU3luY1N0cmVhbUl0ZW0uU3luY0FjdGlvbkhlYXJ0YmVhdEgAEkYKD2RpZmZfb3BlcmF0aW9ucxgUIAEoCzIrLnYxLlN5bmNTdHJlYW1JdGVtLlN5bmNBY3Rpb25EaWZmT3BlcmF0aW9uc0gAEkYKD3NlbmRfb3BlcmF0aW9ucxgVIAEoCzIrLnYxLlN5bmNTdHJlYW1JdGVtLlN5bmNBY3Rpb25TZW5kT3BlcmF0aW9uc0gAEj4KC3NlbmRfY29uZmlnGBYgASgLMicudjEuU3luY1N0cmVhbUl0ZW0uU3luY0FjdGlvblNlbmRDb25maWdIABI8CgpzZXRfY29uZmlnGBggASgLMiYudjEuU3luY1N0cmVhbUl0ZW0uU3luY0FjdGlvblNldENvbmZpZ0gAEkQKDmxpc3RfcmVzb3VyY2VzGBkgASgLMioudjEuU3luY1N0cmVhbUl0ZW0uU3luY0FjdGlvbkxpc3RSZXNvdXJjZXNIABI6Cgh0aHJvdHRsZRjoByABKAsyJS52MS5TeW5jU3RyZWFtSXRlbS5TeW5jQWN0aW9uVGhyb3R0bGVIABp6ChNTeW5jQWN0aW9uSGFuZHNoYWtlEhgKEHByb3RvY29sX3ZlcnNpb24YASABKAMSIQoKcHVibGljX2tleRgCIAEoCzINLnYxLlB1YmxpY0tleRImCgtpbnN0YW5jZV9pZBgDIAEoCzIRLnYxLlNpZ25lZE1lc3NhZ2UaFQoTU3luY0FjdGlvbkhlYXJ0YmVhdBo4ChRTeW5jQWN0aW9uU2VuZENvbmZpZxIgCgZjb25maWcYASABKAsyEC52MS5SZW1vdGVDb25maWcaeQoTU3luY0FjdGlvblNldENvbmZpZxIXCgVyZXBvcxgBIAMoCzIILnYxLlJlcG8SFwoFcGxhbnMYAiADKAsyCC52MS5QbGFuEhcKD3JlcG9zX3RvX2RlbGV0ZRgDIAMoCRIXCg9wbGFuc190b19kZWxldGUYBCADKAkaPQoXU3luY0FjdGlvbkxpc3RSZXNvdXJjZXMSEAoIcmVwb19pZHMYASADKAkSEAoIcGxhbl9pZHMYAiADKAkaKAoVU3luY0FjdGlvbkNvbm5lY3RSZXBvEg8KB3JlcG9faWQYASABKAkaowEKGFN5bmNBY3Rpb25EaWZmT3BlcmF0aW9ucxIwChhoYXZlX29wZXJhdGlvbnNfc2VsZWN0b3IYASABKAsyDi52MS5PcFNlbGVjdG9yEhoKEmhhdmVfb3BlcmF0aW9uX2lkcxgCIAMoAxIdChVoYXZlX29wZXJhdGlvbl9tb2Rub3MYAyADKAMSGgoScmVxdWVzdF9vcGVyYXRpb25zGAQgAygDGj0KGFN5bmNBY3Rpb25TZW5kT3BlcmF0aW9ucxIhCgVldmVudBgBIAEoCzISLnYxLk9wZXJhdGlvbkV2ZW50GiYKElN5bmNBY3Rpb25UaHJvdHRsZRIQCghkZWxheV9tcxgBIAEoAxo4ChlTeW5jRXN0YWJsaXNoU2hhcmVkU2VjcmV0EhsKB2VkMjU1MTkYAiABKAlSCmVkMjU1MTlwdWIitAEKE1JlcG9Db25uZWN0aW9uU3RhdGUSHAoYQ09OTkVDVElPTl9TVEFURV9VTktOT1dOEAASHAoYQ09OTkVDVElPTl9TVEFURV9QRU5ESU5HEAESHgoaQ09OTkVDVElPTl9TVEFURV9DT05ORUNURUQQAhIhCh1DT05ORUNUSU9OX1NUQVRFX1VOQVVUSE9SSVpFRBADEh4KGkNPTk5FQ1RJT05fU1RBVEVfTk9UX0ZPVU5EEARCCAoGYWN0aW9uImAKDFJlbW90ZUNvbmZpZxINCgVtb2RubxgBIAEoBRIPCgd2ZXJzaW9uGAIgASgFEhcKBXJlcG9zGAMgAygLMggudjEuUmVwbxIXCgVwbGFucxgEIAMoCzIILnYxLlBsYW4qoAIKE1N5bmNDb25uZWN0aW9uU3RhdGUSHAoYQ09OTkVDVElPTl9TVEFURV9VTktOT1dOEAASHAoYQ09OTkVDVElPTl9TVEFURV9QRU5ESU5HEAESHgoaQ09OTkVDVElPTl9TVEFURV9DT05ORUNURUQQAhIhCh1DT05ORUNUSU9OX1NUQVRFX0RJU0NPTk5FQ1RFRBADEh8KG0NPTk5FQ1RJT05fU1RBVEVfUkVUUllfV0FJVBAEEh8KG0NPTk5FQ1RJT05fU1RBVEVfRVJST1JfQVVUSBAKEiMKH0NPTk5FQ1RJT05fU1RBVEVfRVJST1JfUFJPVE9DT0wQCxIjCh9DT05ORUNUSU9OX1NUQVRFX0VSUk9SX0lOVEVSTkFMEAwySwoTQmFja3Jlc3RTeW5jU2VydmljZRI0CgRTeW5jEhIudjEuU3luY1N0cmVhbUl0ZW0aEi52MS5TeW5jU3RyZWFtSXRlbSIAKAEwATJkChhCYWNrcmVzdFN5bmNTdGF0ZVNlcnZpY2USSAoXR2V0UGVlclN5bmNTdGF0ZXNTdHJlYW0SGi52MS5TeW5jU3RhdGVTdHJlYW1SZXF1ZXN0Gg0udjEuUGVlclN0YXRlIgAwAUIsWipnaXRodWIuY29tL2dhcmV0aGdlb3JnZS9iYWNrcmVzdC9nZW4vZ28vdjFiBnByb3RvMw", [file_v1_config, file_v1_crypto, file_v1_restic, file_v1_service, file_v1_operations, file_types_value, file_google_protobuf_empty, file_google_api_annotations]);
fileDesc("ChR2MS9zeW5jc2VydmljZS5wcm90bxICdjEijAEKDVR1bm5lbE1lc3NhZ2USDwoHY29ubl9pZBgBIAEoAxINCgVzZXFubxgCIAEoAxIMCgRkYXRhGAMgASgMEg0KBWNsb3NlGAQgASgIEhoKEnB1YmtleV9lY2RoX3gyNTUxORhkIAEoDBIiCgNhbnkY6AcgASgLMhQuZ29vZ2xlLnByb3RvYnVmLkFueSIrChZTeW5jU3RhdGVTdHJlYW1SZXF1ZXN0EhEKCXN1YnNjcmliZRgBIAEoCCLrAQoJUGVlclN0YXRlEhgKEHBlZXJfaW5zdGFuY2VfaWQYASABKAkSEgoKcGVlcl9rZXlpZBgCIAEoCRImCgVzdGF0ZRgDIAEoDjIXLnYxLlN5bmNDb25uZWN0aW9uU3RhdGUSFgoOc3RhdHVzX21lc3NhZ2UYBCABKAkSEwoLa25vd25fcGxhbnMYBSADKAkSEwoLa25vd25fcmVwb3MYBiADKAkSJwoNcmVtb3RlX2NvbmZpZxgHIAEoCzIQLnYxLlJlbW90ZUNvbmZpZxIdChVsYXN0X2hlYXJ0YmVhdF9taWxsaXMYCCABKAMigAwKDlN5bmNTdHJlYW1JdGVtEisKDnNpZ25lZF9tZXNzYWdlGAEgASgLMhEudjEuU2lnbmVkTWVzc2FnZUgAEjsKCWhhbmRzaGFrZRgDIAEoCzImLnYxLlN5bmNTdHJlYW1JdGVtLlN5bmNBY3Rpb25IYW5kc2hha2VIABI7CgloZWFydGJlYXQYBCABKAsyJi52MS5TeW5jU3RyZWFtSXRlbS5TeW5jQWN0aW9uSGVhcnRiZWF0SAASRgoPZGlmZl9vcGVyYXRpb25zGBQgASgLMisudjEuU3luY1N0cmVhbUl0ZW0uU3luY0FjdGlvbkRpZmZPcGVyYXRpb25zSAASRgoPc2VuZF9vcGVyYXRpb25zGBUgASgLMisudjEuU3luY1N0cmVhbUl0ZW0uU3luY0FjdGlvblNlbmRPcGVyYXRpb25zSAASPgoLc2VuZF9jb25maWcYFiABKAsyJy52MS5TeW5jU3RyZWFtSXRlbS5TeW5jQWN0aW9uU2VuZENvbmZpZ0gAEjwKCnNldF9jb25maWcYGCABKAsyJi52MS5TeW5jU3RyZWFtSXRlbS5TeW5jQWN0aW9uU2V0Q29uZmlnSAASRAoObGlzdF9yZXNvdXJjZXMYGSABKAsyKi52MS5TeW5jU3RyZWFtSXRlbS5TeW5jQWN0aW9uTGlzdFJlc291cmNlc0gAEjoKCHRocm90dGxlGOgHIAEoCzIlLnYxLlN5bmNTdHJlYW1JdGVtLlN5bmNBY3Rpb25UaHJvdHRsZUgAGnoKE1N5bmNBY3Rpb25IYW5kc2hha2USGAoQcHJvdG9jb2xfdmVyc2lvbhgBIAEoAxIhCgpwdWJsaWNfa2V5GAIgASgLMg0udjEuUHVibGljS2V5EiYKC2luc3RhbmNlX2lkGAMgASgLMhEudjEuU2lnbmVkTWVzc2FnZRoVChNTeW5jQWN0aW9uSGVhcnRiZWF0GjgKFFN5bmNBY3Rpb25TZW5kQ29uZmlnEiAKBmNvbmZpZxgBIAEoCzIQLnYxLlJlbW90ZUNvbmZpZxp5ChNTeW5jQWN0aW9uU2V0Q29uZmlnEhcKBXJlcG9zGAEgAygLMggudjEuUmVwbxIXCgVwbGFucxgCIAMoCzIILnYxLlBsYW4SFwoPcmVwb3NfdG9fZGVsZXRlGAMgAygJEhcKD3BsYW5zX3RvX2RlbGV0ZRgEIAMoCRo9ChdTeW5jQWN0aW9uTGlzdFJlc291cmNlcxIQCghyZXBvX2lkcxgBIAMoCRIQCghwbGFuX2lkcxgCIAMoCRooChVTeW5jQWN0aW9uQ29ubmVjdFJlcG8SDwoHcmVwb19pZBgBIAEoCRqjAQoYU3luY0FjdGlvbkRpZmZPcGVyYXRpb25zEjAKGGhhdmVfb3BlcmF0aW9uc19zZWxlY3RvchgBIAEoCzIOLnYxLk9wU2VsZWN0b3ISGgoSaGF2ZV9vcGVyYXRpb25faWRzGAIgAygDEh0KFWhhdmVfb3BlcmF0aW9uX21vZG5vcxgDIAMoAxIaChJyZXF1ZXN0X29wZXJhdGlvbnMYBCADKAMaPQoYU3luY0FjdGlvblNlbmRPcGVyYXRpb25zEiEKBWV2ZW50GAEgASgLMhIudjEuT3BlcmF0aW9uRXZlbnQaJgoSU3luY0FjdGlvblRocm90dGxlEhAKCGRlbGF5X21zGAEgASgDGjgKGVN5bmNFc3RhYmxpc2hTaGFyZWRTZWNyZXQSGwoHZWQyNTUxORgCIAEoCVIKZWQyNTUxOXB1YiK0AQoTUmVwb0Nvbm5lY3Rpb25TdGF0ZRIcChhDT05ORUNUSU9OX1NUQVRFX1VOS05PV04QABIcChhDT05ORUNUSU9OX1NUQVRFX1BFTkRJTkcQARIeChpDT05ORUNUSU9OX1NUQVRFX0NPTk5FQ1RFRBACEiEKHUNPTk5FQ1RJT05fU1RBVEVfVU5BVVRIT1JJWkVEEAMSHgoaQ09OTkVDVElPTl9TVEFURV9OT1RfRk9VTkQQBEIICgZhY3Rpb24iYAoMUmVtb3RlQ29uZmlnEg0KBW1vZG5vGAEgASgFEg8KB3ZlcnNpb24YAiABKAUSFwoFcmVwb3MYAyADKAsyCC52MS5SZXBvEhcKBXBsYW5zGAQgAygLMggudjEuUGxhbiqgAgoTU3luY0Nvbm5lY3Rpb25TdGF0ZRIcChhDT05ORUNUSU9OX1NUQVRFX1VOS05PV04QABIcChhDT05ORUNUSU9OX1NUQVRFX1BFTkRJTkcQARIeChpDT05ORUNUSU9OX1NUQVRFX0NPTk5FQ1RFRBACEiEKHUNPTk5FQ1RJT05fU1RBVEVfRElTQ09OTkVDVEVEEAMSHwobQ09OTkVDVElPTl9TVEFURV9SRVRSWV9XQUlUEAQSHwobQ09OTkVDVElPTl9TVEFURV9FUlJPUl9BVVRIEAoSIwofQ09OTkVDVElPTl9TVEFURV9FUlJPUl9QUk9UT0NPTBALEiMKH0NPTk5FQ1RJT05fU1RBVEVfRVJST1JfSU5URVJOQUwQDDJFCg1UdW5uZWxTZXJ2aWNlEjQKBlR1bm5lbBIRLnYxLlR1bm5lbE1lc3NhZ2UaES52MS5UdW5uZWxNZXNzYWdlIgAoATABMksKE0JhY2tyZXN0U3luY1NlcnZpY2USNAoEU3luYxISLnYxLlN5bmNTdHJlYW1JdGVtGhIudjEuU3luY1N0cmVhbUl0ZW0iACgBMAEyZAoYQmFja3Jlc3RTeW5jU3RhdGVTZXJ2aWNlEkgKF0dldFBlZXJTeW5jU3RhdGVzU3RyZWFtEhoudjEuU3luY1N0YXRlU3RyZWFtUmVxdWVzdBoNLnYxLlBlZXJTdGF0ZSIAMAFCLFoqZ2l0aHViLmNvbS9nYXJldGhnZW9yZ2UvYmFja3Jlc3QvZ2VuL2dvL3YxYgZwcm90bzM", [file_v1_config, file_v1_crypto, file_v1_restic, file_v1_service, file_v1_operations, file_types_value, file_google_protobuf_empty, file_google_api_annotations, file_google_protobuf_any]);
/**
* @generated from message v1.TunnelMessage
*/
export type TunnelMessage = Message<"v1.TunnelMessage"> & {
/**
* The connection ID this request belongs to, enables multiplexing.
*
* @generated from field: int64 conn_id = 1;
*/
connId: bigint;
/**
* @generated from field: int64 seqno = 2;
*/
seqno: bigint;
/**
* The data to send, this is a raw byte stream.
*
* @generated from field: bytes data = 3;
*/
data: Uint8Array;
/**
* If true, the write end should be closed after this request.
*
* @generated from field: bool close = 4;
*/
close: boolean;
/**
* The public key used for ECDH key exchange, binary encoded.
*
* @generated from field: bytes pubkey_ecdh_x25519 = 100;
*/
pubkeyEcdhX25519: Uint8Array;
/**
* Available to allow sending custom data down the tunnel in the initial handshake.
*
* @generated from field: google.protobuf.Any any = 1000;
*/
any?: Any;
};
/**
* Describes the message v1.TunnelMessage.
* Use `create(TunnelMessageSchema)` to create a new message.
*/
export const TunnelMessageSchema: GenMessage<TunnelMessage> = /*@__PURE__*/
messageDesc(file_v1_syncservice, 0);
/**
* @generated from message v1.SyncStateStreamRequest
@@ -41,7 +94,7 @@ export type SyncStateStreamRequest = Message<"v1.SyncStateStreamRequest"> & {
* Use `create(SyncStateStreamRequestSchema)` to create a new message.
*/
export const SyncStateStreamRequestSchema: GenMessage<SyncStateStreamRequest> = /*@__PURE__*/
messageDesc(file_v1_syncservice, 0);
messageDesc(file_v1_syncservice, 1);
/**
* @generated from message v1.PeerState
@@ -101,7 +154,7 @@ export type PeerState = Message<"v1.PeerState"> & {
* Use `create(PeerStateSchema)` to create a new message.
*/
export const PeerStateSchema: GenMessage<PeerState> = /*@__PURE__*/
messageDesc(file_v1_syncservice, 1);
messageDesc(file_v1_syncservice, 2);
/**
* @generated from message v1.SyncStreamItem
@@ -172,7 +225,7 @@ export type SyncStreamItem = Message<"v1.SyncStreamItem"> & {
* Use `create(SyncStreamItemSchema)` to create a new message.
*/
export const SyncStreamItemSchema: GenMessage<SyncStreamItem> = /*@__PURE__*/
messageDesc(file_v1_syncservice, 2);
messageDesc(file_v1_syncservice, 3);
/**
* @generated from message v1.SyncStreamItem.SyncActionHandshake
@@ -199,7 +252,7 @@ export type SyncStreamItem_SyncActionHandshake = Message<"v1.SyncStreamItem.Sync
* Use `create(SyncStreamItem_SyncActionHandshakeSchema)` to create a new message.
*/
export const SyncStreamItem_SyncActionHandshakeSchema: GenMessage<SyncStreamItem_SyncActionHandshake> = /*@__PURE__*/
messageDesc(file_v1_syncservice, 2, 0);
messageDesc(file_v1_syncservice, 3, 0);
/**
* SyncActionHeartbeat is sent periodically to keep the connection alive.
@@ -214,7 +267,7 @@ export type SyncStreamItem_SyncActionHeartbeat = Message<"v1.SyncStreamItem.Sync
* Use `create(SyncStreamItem_SyncActionHeartbeatSchema)` to create a new message.
*/
export const SyncStreamItem_SyncActionHeartbeatSchema: GenMessage<SyncStreamItem_SyncActionHeartbeat> = /*@__PURE__*/
messageDesc(file_v1_syncservice, 2, 1);
messageDesc(file_v1_syncservice, 3, 1);
/**
* @generated from message v1.SyncStreamItem.SyncActionSendConfig
@@ -231,7 +284,7 @@ export type SyncStreamItem_SyncActionSendConfig = Message<"v1.SyncStreamItem.Syn
* Use `create(SyncStreamItem_SyncActionSendConfigSchema)` to create a new message.
*/
export const SyncStreamItem_SyncActionSendConfigSchema: GenMessage<SyncStreamItem_SyncActionSendConfig> = /*@__PURE__*/
messageDesc(file_v1_syncservice, 2, 2);
messageDesc(file_v1_syncservice, 3, 2);
/**
* @generated from message v1.SyncStreamItem.SyncActionSetConfig
@@ -263,7 +316,7 @@ export type SyncStreamItem_SyncActionSetConfig = Message<"v1.SyncStreamItem.Sync
* Use `create(SyncStreamItem_SyncActionSetConfigSchema)` to create a new message.
*/
export const SyncStreamItem_SyncActionSetConfigSchema: GenMessage<SyncStreamItem_SyncActionSetConfig> = /*@__PURE__*/
messageDesc(file_v1_syncservice, 2, 3);
messageDesc(file_v1_syncservice, 3, 3);
/**
* @generated from message v1.SyncStreamItem.SyncActionListResources
@@ -289,7 +342,7 @@ export type SyncStreamItem_SyncActionListResources = Message<"v1.SyncStreamItem.
* Use `create(SyncStreamItem_SyncActionListResourcesSchema)` to create a new message.
*/
export const SyncStreamItem_SyncActionListResourcesSchema: GenMessage<SyncStreamItem_SyncActionListResources> = /*@__PURE__*/
messageDesc(file_v1_syncservice, 2, 4);
messageDesc(file_v1_syncservice, 3, 4);
/**
* @generated from message v1.SyncStreamItem.SyncActionConnectRepo
@@ -306,7 +359,7 @@ export type SyncStreamItem_SyncActionConnectRepo = Message<"v1.SyncStreamItem.Sy
* Use `create(SyncStreamItem_SyncActionConnectRepoSchema)` to create a new message.
*/
export const SyncStreamItem_SyncActionConnectRepoSchema: GenMessage<SyncStreamItem_SyncActionConnectRepo> = /*@__PURE__*/
messageDesc(file_v1_syncservice, 2, 5);
messageDesc(file_v1_syncservice, 3, 5);
/**
* @generated from message v1.SyncStreamItem.SyncActionDiffOperations
@@ -343,7 +396,7 @@ export type SyncStreamItem_SyncActionDiffOperations = Message<"v1.SyncStreamItem
* Use `create(SyncStreamItem_SyncActionDiffOperationsSchema)` to create a new message.
*/
export const SyncStreamItem_SyncActionDiffOperationsSchema: GenMessage<SyncStreamItem_SyncActionDiffOperations> = /*@__PURE__*/
messageDesc(file_v1_syncservice, 2, 6);
messageDesc(file_v1_syncservice, 3, 6);
/**
* @generated from message v1.SyncStreamItem.SyncActionSendOperations
@@ -360,7 +413,7 @@ export type SyncStreamItem_SyncActionSendOperations = Message<"v1.SyncStreamItem
* Use `create(SyncStreamItem_SyncActionSendOperationsSchema)` to create a new message.
*/
export const SyncStreamItem_SyncActionSendOperationsSchema: GenMessage<SyncStreamItem_SyncActionSendOperations> = /*@__PURE__*/
messageDesc(file_v1_syncservice, 2, 7);
messageDesc(file_v1_syncservice, 3, 7);
/**
* @generated from message v1.SyncStreamItem.SyncActionThrottle
@@ -377,7 +430,7 @@ export type SyncStreamItem_SyncActionThrottle = Message<"v1.SyncStreamItem.SyncA
* Use `create(SyncStreamItem_SyncActionThrottleSchema)` to create a new message.
*/
export const SyncStreamItem_SyncActionThrottleSchema: GenMessage<SyncStreamItem_SyncActionThrottle> = /*@__PURE__*/
messageDesc(file_v1_syncservice, 2, 8);
messageDesc(file_v1_syncservice, 3, 8);
/**
* @generated from message v1.SyncStreamItem.SyncEstablishSharedSecret
@@ -399,7 +452,7 @@ export type SyncStreamItem_SyncEstablishSharedSecret = Message<"v1.SyncStreamIte
* Use `create(SyncStreamItem_SyncEstablishSharedSecretSchema)` to create a new message.
*/
export const SyncStreamItem_SyncEstablishSharedSecretSchema: GenMessage<SyncStreamItem_SyncEstablishSharedSecret> = /*@__PURE__*/
messageDesc(file_v1_syncservice, 2, 9);
messageDesc(file_v1_syncservice, 3, 9);
/**
* @generated from enum v1.SyncStreamItem.RepoConnectionState
@@ -437,7 +490,7 @@ export enum SyncStreamItem_RepoConnectionState {
* Describes the enum v1.SyncStreamItem.RepoConnectionState.
*/
export const SyncStreamItem_RepoConnectionStateSchema: GenEnum<SyncStreamItem_RepoConnectionState> = /*@__PURE__*/
enumDesc(file_v1_syncservice, 2, 0);
enumDesc(file_v1_syncservice, 3, 0);
/**
* RemoteConfig contains shareable properties from a remote backrest instance.
@@ -475,7 +528,7 @@ export type RemoteConfig = Message<"v1.RemoteConfig"> & {
* Use `create(RemoteConfigSchema)` to create a new message.
*/
export const RemoteConfigSchema: GenMessage<RemoteConfig> = /*@__PURE__*/
messageDesc(file_v1_syncservice, 3);
messageDesc(file_v1_syncservice, 4);
/**
* @generated from enum v1.SyncConnectionState
@@ -528,6 +581,23 @@ export enum SyncConnectionState {
export const SyncConnectionStateSchema: GenEnum<SyncConnectionState> = /*@__PURE__*/
enumDesc(file_v1_syncservice, 0);
/**
* TunnelService allows inverted communicatons from server to client where the server can initiate requests to the client.
*
* @generated from service v1.TunnelService
*/
export const TunnelService: GenService<{
/**
* @generated from rpc v1.TunnelService.Tunnel
*/
tunnel: {
methodKind: "bidi_streaming";
input: typeof TunnelMessageSchema;
output: typeof TunnelMessageSchema;
},
}> = /*@__PURE__*/
serviceDesc(file_v1_syncservice, 0);
/**
* BackrestSyncService provides methods to sync data between backrest instances.
* This service provides its own authentication and authorization.
@@ -544,7 +614,7 @@ export const BackrestSyncService: GenService<{
output: typeof SyncStreamItemSchema;
},
}> = /*@__PURE__*/
serviceDesc(file_v1_syncservice, 0);
serviceDesc(file_v1_syncservice, 1);
/**
* BackrestSyncStateService provides methods to query the sync state of known hosts and clients.
@@ -562,5 +632,5 @@ export const BackrestSyncStateService: GenService<{
output: typeof PeerStateSchema;
},
}> = /*@__PURE__*/
serviceDesc(file_v1_syncservice, 1);
serviceDesc(file_v1_syncservice, 2);