lib/model: Introducer can remove stuff it introduced (fixes #1015)

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3522
This commit is contained in:
Audrius Butkevicius 2016-11-07 16:40:48 +00:00 committed by Jakob Borg
parent bfb48b5dde
commit a1a91d5ef4
6 changed files with 739 additions and 205 deletions

View File

@ -9,12 +9,14 @@ package config
import "github.com/syncthing/syncthing/lib/protocol"
type DeviceConfiguration struct {
DeviceID protocol.DeviceID `xml:"id,attr" json:"deviceID"`
Name string `xml:"name,attr,omitempty" json:"name"`
Addresses []string `xml:"address,omitempty" json:"addresses"`
Compression protocol.Compression `xml:"compression,attr" json:"compression"`
CertName string `xml:"certName,attr,omitempty" json:"certName"`
Introducer bool `xml:"introducer,attr" json:"introducer"`
DeviceID protocol.DeviceID `xml:"id,attr" json:"deviceID"`
Name string `xml:"name,attr,omitempty" json:"name"`
Addresses []string `xml:"address,omitempty" json:"addresses"`
Compression protocol.Compression `xml:"compression,attr" json:"compression"`
CertName string `xml:"certName,attr,omitempty" json:"certName"`
Introducer bool `xml:"introducer,attr" json:"introducer"`
SkipIntroductionRemovals bool `xml:"skipIntroductionRemovals,attr" json:"skipIntroductionRemovals"`
IntroducedBy protocol.DeviceID `xml:"introducedBy,attr" json:"introducedBy"`
}
func NewDeviceConfiguration(id protocol.DeviceID, name string) DeviceConfiguration {

View File

@ -45,7 +45,8 @@ type FolderConfiguration struct {
}
type FolderDeviceConfiguration struct {
DeviceID protocol.DeviceID `xml:"id,attr" json:"deviceID"`
DeviceID protocol.DeviceID `xml:"id,attr" json:"deviceID"`
IntroducedBy protocol.DeviceID `xml:"introducedBy,attr" json:"introducedBy"`
}
func NewFolderConfiguration(id, path string) FolderConfiguration {

View File

@ -83,7 +83,7 @@ type Model struct {
folderCfgs map[string]config.FolderConfiguration // folder -> cfg
folderFiles map[string]*db.FileSet // folder -> files
folderDevices map[string][]protocol.DeviceID // folder -> deviceIDs
folderDevices folderDeviceSet // folder -> deviceIDs
deviceFolders map[protocol.DeviceID][]string // deviceID -> folders
deviceStatRefs map[protocol.DeviceID]*stats.DeviceStatisticsReference // deviceID -> statsRef
folderIgnores map[string]*ignore.Matcher // folder -> matcher object
@ -144,7 +144,7 @@ func NewModel(cfg *config.Wrapper, id protocol.DeviceID, deviceName, clientName,
clientVersion: clientVersion,
folderCfgs: make(map[string]config.FolderConfiguration),
folderFiles: make(map[string]*db.FileSet),
folderDevices: make(map[string][]protocol.DeviceID),
folderDevices: make(folderDeviceSet),
deviceFolders: make(map[protocol.DeviceID][]string),
deviceStatRefs: make(map[protocol.DeviceID]*stats.DeviceStatisticsReference),
folderIgnores: make(map[string]*ignore.Matcher),
@ -303,9 +303,8 @@ func (m *Model) addFolderLocked(cfg config.FolderConfiguration) {
m.folderCfgs[cfg.ID] = cfg
m.folderFiles[cfg.ID] = db.NewFileSet(cfg.ID, m.db)
m.folderDevices[cfg.ID] = make([]protocol.DeviceID, len(cfg.Devices))
for i, device := range cfg.Devices {
m.folderDevices[cfg.ID][i] = device.DeviceID
for _, device := range cfg.Devices {
m.folderDevices.set(device.DeviceID, cfg.ID)
m.deviceFolders[device.DeviceID] = append(m.deviceFolders[device.DeviceID], cfg.ID)
}
@ -335,7 +334,7 @@ func (m *Model) tearDownFolderLocked(folder string) {
}
// Close connections to affected devices
for _, dev := range m.folderDevices[folder] {
for dev := range m.folderDevices[folder] {
if conn, ok := m.conn[dev]; ok {
closeRawConn(conn)
}
@ -872,80 +871,177 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
}
}
var changed bool
if m.cfg.Devices()[deviceID].Introducer {
// This device is an introducer. Go through the announced lists of folders
// and devices and add what we are missing.
for _, folder := range cm.Folders {
if _, ok := m.folderDevices[folder.ID]; !ok {
continue
}
nextDevice:
for _, device := range folder.Devices {
if _, ok := m.cfg.Devices()[device.ID]; !ok {
// The device is currently unknown. Add it to the config.
addresses := []string{"dynamic"}
for _, addr := range device.Addresses {
if addr != "dynamic" {
addresses = append(addresses, addr)
}
}
l.Infof("Adding device %v to config (vouched for by introducer %v)", device.ID, deviceID)
newDeviceCfg := config.DeviceConfiguration{
DeviceID: device.ID,
Name: device.Name,
Compression: m.cfg.Devices()[deviceID].Compression,
Addresses: addresses,
CertName: device.CertName,
}
// The introducers' introducers are also our introducers.
if device.Introducer {
l.Infof("Device %v is now also an introducer", device.ID)
newDeviceCfg.Introducer = true
}
m.cfg.SetDevice(newDeviceCfg)
changed = true
}
for _, er := range m.deviceFolders[device.ID] {
if er == folder.ID {
// We already share the folder with this device, so
// nothing to do.
continue nextDevice
}
}
// We don't yet share this folder with this device. Add the device
// to sharing list of the folder.
l.Infof("Adding device %v to share %q (vouched for by introducer %v)", device.ID, folder.ID, deviceID)
m.deviceFolders[device.ID] = append(m.deviceFolders[device.ID], folder.ID)
m.folderDevices[folder.ID] = append(m.folderDevices[folder.ID], device.ID)
folderCfg := m.cfg.Folders()[folder.ID]
folderCfg.Devices = append(folderCfg.Devices, config.FolderDeviceConfiguration{
DeviceID: device.ID,
})
m.cfg.SetFolder(folderCfg)
changed = true
}
var changed = false
if deviceCfg := m.cfg.Devices()[deviceID]; deviceCfg.Introducer {
foldersDevices, introduced := m.handleIntroductions(deviceCfg, cm)
if introduced {
changed = true
}
// If permitted, check if the introducer has unshare devices/folders with
// some of the devices/folders that we know were introduced to us by him.
if !deviceCfg.SkipIntroductionRemovals && m.handleDeintroductions(deviceCfg, cm, foldersDevices) {
changed = true
}
}
if changed {
m.cfg.Save()
if err := m.cfg.Save(); err != nil {
l.Warnln("Failed to save config", err)
}
}
}
// handleIntroductions handles adding devices/shares that are shared by an introducer device
func (m *Model) handleIntroductions(introducerCfg config.DeviceConfiguration, cm protocol.ClusterConfig) (folderDeviceSet, bool) {
// This device is an introducer. Go through the announced lists of folders
// and devices and add what we are missing, remove what we have extra that
// has been introducer by the introducer.
changed := false
foldersDevices := make(folderDeviceSet)
for _, folder := range cm.Folders {
// We don't have this folder, skip.
if _, ok := m.folderDevices[folder.ID]; !ok {
continue
}
// Adds devices which we do not have, but the introducer has
// for the folders that we have in common. Also, shares folders
// with devices that we have in common, yet are currently not sharing
// the folder.
nextDevice:
for _, device := range folder.Devices {
foldersDevices.set(device.ID, folder.ID)
if _, ok := m.cfg.Devices()[device.ID]; !ok {
// The device is currently unknown. Add it to the config.
m.introduceDevice(device, introducerCfg)
changed = true
}
for _, er := range m.deviceFolders[device.ID] {
if er == folder.ID {
// We already share the folder with this device, so
// nothing to do.
continue nextDevice
}
}
// We don't yet share this folder with this device. Add the device
// to sharing list of the folder.
m.introduceDeviceToFolder(device, folder, introducerCfg)
changed = true
}
}
return foldersDevices, changed
}
// handleIntroductions handles removals of devices/shares that are removed by an introducer device
func (m *Model) handleDeintroductions(introducerCfg config.DeviceConfiguration, cm protocol.ClusterConfig, foldersDevices folderDeviceSet) bool {
changed := false
foldersIntroducedByOthers := make(folderDeviceSet)
// Check if we should unshare some folders, if the introducer has unshared them.
for _, folderCfg := range m.cfg.Folders() {
folderChanged := false
for i := 0; i < len(folderCfg.Devices); i++ {
if folderCfg.Devices[i].IntroducedBy == introducerCfg.DeviceID {
if !foldersDevices.has(folderCfg.Devices[i].DeviceID, folderCfg.ID) {
// We could not find that folder shared on the introducer with the device that was introduced to us.
// We should follow and unshare aswell.
l.Infof("Unsharing folder %q with %v as introducer %v no longer shares the folder with that device", folderCfg.ID, folderCfg.Devices[i].DeviceID, folderCfg.Devices[i].IntroducedBy)
folderCfg.Devices = append(folderCfg.Devices[:i], folderCfg.Devices[i+1:]...)
i--
folderChanged = true
}
} else {
foldersIntroducedByOthers.set(folderCfg.Devices[i].DeviceID, folderCfg.ID)
}
}
// We've modified the folder, hence update it.
if folderChanged {
m.cfg.SetFolder(folderCfg)
changed = true
}
}
// Check if we should remove some devices, if the introducer no longer shares any folder with them.
// Yet do not remove if we share other folders that haven't been introduced by the introducer.
raw := m.cfg.Raw()
deviceChanged := false
for i := 0; i < len(raw.Devices); i++ {
if raw.Devices[i].IntroducedBy == introducerCfg.DeviceID {
if !foldersDevices.hasDevice(raw.Devices[i].DeviceID) {
if foldersIntroducedByOthers.hasDevice(raw.Devices[i].DeviceID) {
l.Infof("Would have removed %v as %v no longer shares any folders, yet there are other folders that are shared with this device that haven't been introduced by this introducer.", raw.Devices[i].DeviceID, raw.Devices[i].IntroducedBy)
continue
}
// The introducer no longer shares any folder with the device, remove the device.
l.Infof("Removing device %v as introducer %v no longer shares any folders with that device", raw.Devices[i].DeviceID, raw.Devices[i].IntroducedBy)
raw.Devices = append(raw.Devices[:i], raw.Devices[i+1:]...)
i--
deviceChanged = true
}
}
}
// We've removed a device, replace the config.
if deviceChanged {
if err := m.cfg.Replace(raw); err != nil {
l.Warnln("Failed to save config", err)
}
changed = true
}
return changed
}
func (m *Model) introduceDevice(device protocol.Device, introducerCfg config.DeviceConfiguration) {
addresses := []string{"dynamic"}
for _, addr := range device.Addresses {
if addr != "dynamic" {
addresses = append(addresses, addr)
}
}
l.Infof("Adding device %v to config (vouched for by introducer %v)", device.ID, introducerCfg.DeviceID)
newDeviceCfg := config.DeviceConfiguration{
DeviceID: device.ID,
Name: device.Name,
Compression: introducerCfg.Compression,
Addresses: addresses,
CertName: device.CertName,
IntroducedBy: introducerCfg.DeviceID,
}
// The introducers' introducers are also our introducers.
if device.Introducer {
l.Infof("Device %v is now also an introducer", device.ID)
newDeviceCfg.Introducer = true
newDeviceCfg.SkipIntroductionRemovals = device.SkipIntroductionRemovals
}
m.cfg.SetDevice(newDeviceCfg)
}
func (m *Model) introduceDeviceToFolder(device protocol.Device, folder protocol.Folder, introducerCfg config.DeviceConfiguration) {
l.Infof("Sharing folder %q with %v (vouched for by introducer %v)", folder.ID, device.ID, introducerCfg.DeviceID)
m.deviceFolders[device.ID] = append(m.deviceFolders[device.ID], folder.ID)
m.folderDevices.set(device.ID, folder.ID)
folderCfg := m.cfg.Folders()[folder.ID]
folderCfg.Devices = append(folderCfg.Devices, config.FolderDeviceConfiguration{
DeviceID: device.ID,
IntroducedBy: introducerCfg.DeviceID,
})
m.cfg.SetFolder(folderCfg)
}
// Closed is called when a connection has been closed
func (m *Model) Closed(conn protocol.Connection, err error) {
device := conn.ID()
@ -1469,7 +1565,6 @@ func (m *Model) updateLocalsFromScanning(folder string, fs []protocol.FileInfo)
m.fmut.RLock()
folderCfg := m.folderCfgs[folder]
m.fmut.RUnlock()
// Fire the LocalChangeDetected event to notify listeners about local updates.
m.localChangeDetected(folderCfg, fs)
}
@ -1876,7 +1971,7 @@ func (m *Model) generateClusterConfig(device protocol.DeviceID) protocol.Cluster
DisableTempIndexes: folderCfg.DisableTempIndexes,
}
for _, device := range m.folderDevices[folder] {
for device := range m.folderDevices[folder] {
// DeviceID is a value type, but with an underlying array. Copy it
// so we don't grab aliases to the same array later on in device[:]
device := device
@ -1999,8 +2094,8 @@ func (m *Model) RemoteSequence(folder string) (int64, bool) {
}
var ver int64
for _, n := range m.folderDevices[folder] {
ver += fs.Sequence(n)
for device := range m.folderDevices[folder] {
ver += fs.Sequence(device)
}
return ver, true
@ -2094,7 +2189,7 @@ func (m *Model) Availability(folder, file string, version protocol.Vector, block
}
}
for _, device := range devices {
for device := range devices {
if m.deviceDownloads[device].Has(folder, file, version, int32(block.Offset/protocol.BlockSize)) {
availabilities = append(availabilities, Availability{ID: device, FromTemporary: true})
}
@ -2480,3 +2575,32 @@ func shouldIgnore(file db.FileIntf, matcher *ignore.Matcher, ignoreDelete bool)
return false
}
// folderDeviceSet is a set of (folder, deviceID) pairs
type folderDeviceSet map[string]map[protocol.DeviceID]struct{}
// set adds the (dev, folder) pair to the set
func (s folderDeviceSet) set(dev protocol.DeviceID, folder string) {
devs, ok := s[folder]
if !ok {
devs = make(map[protocol.DeviceID]struct{})
s[folder] = devs
}
devs[dev] = struct{}{}
}
// has returns true if the (dev, folder) pair is in the set
func (s folderDeviceSet) has(dev protocol.DeviceID, folder string) bool {
_, ok := s[folder][dev]
return ok
}
// hasDevice returns true if the device is set on any folder
func (s folderDeviceSet) hasDevice(dev protocol.DeviceID) bool {
for _, devices := range s {
if _, ok := devices[dev]; ok {
return true
}
}
return false
}

View File

@ -478,6 +478,376 @@ func TestClusterConfig(t *testing.T) {
}
}
func TestIntroducer(t *testing.T) {
var introducedByAnyone protocol.DeviceID
// LocalDeviceID is a magic value meaning don't check introducer
contains := func(cfg config.FolderConfiguration, id, introducedBy protocol.DeviceID) bool {
for _, dev := range cfg.Devices {
if dev.DeviceID.Equals(id) {
if introducedBy.Equals(introducedByAnyone) {
return true
}
return introducedBy.Equals(introducedBy)
}
}
return false
}
newState := func(cfg config.Configuration) (*config.Wrapper, *Model) {
db := db.OpenMemory()
wcfg := config.Wrap("/tmp/test", cfg)
m := NewModel(wcfg, protocol.LocalDeviceID, "device", "syncthing", "dev", db, nil)
for _, folder := range cfg.Folders {
m.AddFolder(folder)
}
m.ServeBackground()
m.AddConnection(connections.Connection{
IntermediateConnection: connections.IntermediateConnection{
Conn: tls.Client(&fakeConn{}, nil),
},
Connection: &FakeConnection{
id: device1,
},
}, protocol.HelloResult{})
return wcfg, m
}
wcfg, m := newState(config.Configuration{
Devices: []config.DeviceConfiguration{
{
DeviceID: device1,
Introducer: true,
},
},
Folders: []config.FolderConfiguration{
{
ID: "folder1",
Devices: []config.FolderDeviceConfiguration{
{DeviceID: device1},
},
},
{
ID: "folder2",
Devices: []config.FolderDeviceConfiguration{
{DeviceID: device1},
},
},
},
})
m.ClusterConfig(device1, protocol.ClusterConfig{
Folders: []protocol.Folder{
{
ID: "folder1",
Devices: []protocol.Device{
{
ID: device2,
Introducer: true,
SkipIntroductionRemovals: true,
},
},
},
},
})
if newDev, ok := wcfg.Device(device2); !ok || !newDev.Introducer || !newDev.SkipIntroductionRemovals {
t.Error("devie 2 missing or wrong flags")
}
if !contains(wcfg.Folders()["folder1"], device2, device1) {
t.Error("expected folder 1 to have device2 introduced by device 1")
}
wcfg, m = newState(config.Configuration{
Devices: []config.DeviceConfiguration{
{
DeviceID: device1,
Introducer: true,
},
{
DeviceID: device2,
IntroducedBy: device1,
},
},
Folders: []config.FolderConfiguration{
{
ID: "folder1",
Devices: []config.FolderDeviceConfiguration{
{DeviceID: device1},
{DeviceID: device2, IntroducedBy: device1},
},
},
{
ID: "folder2",
Devices: []config.FolderDeviceConfiguration{
{DeviceID: device1},
},
},
},
})
m.ClusterConfig(device1, protocol.ClusterConfig{
Folders: []protocol.Folder{
{
ID: "folder2",
Devices: []protocol.Device{
{
ID: device2,
Introducer: true,
SkipIntroductionRemovals: true,
},
},
},
},
})
// Should not get introducer, as it's already unset, and it's an existing device.
if newDev, ok := wcfg.Device(device2); !ok || newDev.Introducer || newDev.SkipIntroductionRemovals {
t.Error("device 2 missing or changed flags")
}
if contains(wcfg.Folders()["folder1"], device2, introducedByAnyone) {
t.Error("expected device 2 to be removed from folder 1")
}
if !contains(wcfg.Folders()["folder2"], device2, device1) {
t.Error("expected device 2 to be added to folder 2")
}
wcfg, m = newState(config.Configuration{
Devices: []config.DeviceConfiguration{
{
DeviceID: device1,
Introducer: true,
},
{
DeviceID: device2,
IntroducedBy: device1,
},
},
Folders: []config.FolderConfiguration{
{
ID: "folder1",
Devices: []config.FolderDeviceConfiguration{
{DeviceID: device1},
{DeviceID: device2, IntroducedBy: device1},
},
},
{
ID: "folder2",
Devices: []config.FolderDeviceConfiguration{
{DeviceID: device1},
{DeviceID: device2, IntroducedBy: device1},
},
},
},
})
m.ClusterConfig(device1, protocol.ClusterConfig{})
if _, ok := wcfg.Device(device2); ok {
t.Error("device 2 should have been removed")
}
if contains(wcfg.Folders()["folder1"], device2, introducedByAnyone) {
t.Error("expected device 2 to be removed from folder 1")
}
if contains(wcfg.Folders()["folder2"], device2, introducedByAnyone) {
t.Error("expected device 2 to be removed from folder 2")
}
// Two cases when removals should not happen
// 1. Introducer flag no longer set on device
wcfg, m = newState(config.Configuration{
Devices: []config.DeviceConfiguration{
{
DeviceID: device1,
Introducer: false,
},
{
DeviceID: device2,
IntroducedBy: device1,
},
},
Folders: []config.FolderConfiguration{
{
ID: "folder1",
Devices: []config.FolderDeviceConfiguration{
{DeviceID: device1},
{DeviceID: device2, IntroducedBy: device1},
},
},
{
ID: "folder2",
Devices: []config.FolderDeviceConfiguration{
{DeviceID: device1},
{DeviceID: device2, IntroducedBy: device1},
},
},
},
})
m.ClusterConfig(device1, protocol.ClusterConfig{})
if _, ok := wcfg.Device(device2); !ok {
t.Error("device 2 should not have been removed")
}
if !contains(wcfg.Folders()["folder1"], device2, device1) {
t.Error("expected device 2 not to be removed from folder 1")
}
if !contains(wcfg.Folders()["folder2"], device2, device1) {
t.Error("expected device 2 not to be removed from folder 2")
}
// 2. SkipIntroductionRemovals is set
wcfg, m = newState(config.Configuration{
Devices: []config.DeviceConfiguration{
{
DeviceID: device1,
Introducer: true,
SkipIntroductionRemovals: true,
},
{
DeviceID: device2,
IntroducedBy: device1,
},
},
Folders: []config.FolderConfiguration{
{
ID: "folder1",
Devices: []config.FolderDeviceConfiguration{
{DeviceID: device1},
{DeviceID: device2, IntroducedBy: device1},
},
},
{
ID: "folder2",
Devices: []config.FolderDeviceConfiguration{
{DeviceID: device1},
},
},
},
})
m.ClusterConfig(device1, protocol.ClusterConfig{
Folders: []protocol.Folder{
{
ID: "folder2",
Devices: []protocol.Device{
{
ID: device2,
Introducer: true,
SkipIntroductionRemovals: true,
},
},
},
},
})
if _, ok := wcfg.Device(device2); !ok {
t.Error("device 2 should not have been removed")
}
if !contains(wcfg.Folders()["folder1"], device2, device1) {
t.Error("expected device 2 not to be removed from folder 1")
}
if !contains(wcfg.Folders()["folder2"], device2, device1) {
t.Error("expected device 2 not to be added to folder 2")
}
// Test device not being removed as it's shared without an introducer.
wcfg, m = newState(config.Configuration{
Devices: []config.DeviceConfiguration{
{
DeviceID: device1,
Introducer: true,
},
{
DeviceID: device2,
IntroducedBy: device1,
},
},
Folders: []config.FolderConfiguration{
{
ID: "folder1",
Devices: []config.FolderDeviceConfiguration{
{DeviceID: device1},
{DeviceID: device2, IntroducedBy: device1},
},
},
{
ID: "folder2",
Devices: []config.FolderDeviceConfiguration{
{DeviceID: device1},
{DeviceID: device2},
},
},
},
})
m.ClusterConfig(device1, protocol.ClusterConfig{})
if _, ok := wcfg.Device(device2); !ok {
t.Error("device 2 should not have been removed")
}
if contains(wcfg.Folders()["folder1"], device2, introducedByAnyone) {
t.Error("expected device 2 to be removed from folder 1")
}
if !contains(wcfg.Folders()["folder2"], device2, introducedByAnyone) {
t.Error("expected device 2 not to be removed from folder 2")
}
// Test device not being removed as it's shared by a different introducer.
wcfg, m = newState(config.Configuration{
Devices: []config.DeviceConfiguration{
{
DeviceID: device1,
Introducer: true,
},
{
DeviceID: device2,
IntroducedBy: device1,
},
},
Folders: []config.FolderConfiguration{
{
ID: "folder1",
Devices: []config.FolderDeviceConfiguration{
{DeviceID: device1},
{DeviceID: device2, IntroducedBy: device1},
},
},
{
ID: "folder2",
Devices: []config.FolderDeviceConfiguration{
{DeviceID: device1},
{DeviceID: device2, IntroducedBy: protocol.LocalDeviceID},
},
},
},
})
m.ClusterConfig(device1, protocol.ClusterConfig{})
if _, ok := wcfg.Device(device2); !ok {
t.Error("device 2 should not have been removed")
}
if contains(wcfg.Folders()["folder1"], device2, introducedByAnyone) {
t.Error("expected device 2 to be removed from folder 1")
}
if !contains(wcfg.Folders()["folder2"], device2, introducedByAnyone) {
t.Error("expected device 2 not to be removed from folder 2")
}
}
func TestIgnores(t *testing.T) {
arrEqual := func(a, b []string) bool {
if len(a) != len(b) {
@ -1623,7 +1993,7 @@ func TestSharedWithClearedOnDisconnect(t *testing.T) {
t.Error("folder missing?")
}
for _, id := range fdevs {
for id := range fdevs {
if id == device2 {
t.Error("still there")
}

View File

@ -255,14 +255,15 @@ func (*Folder) ProtoMessage() {}
func (*Folder) Descriptor() ([]byte, []int) { return fileDescriptorBep, []int{3} }
type Device struct {
ID DeviceID `protobuf:"bytes,1,opt,name=id,proto3,customtype=DeviceID" json:"id"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Addresses []string `protobuf:"bytes,3,rep,name=addresses" json:"addresses,omitempty"`
Compression Compression `protobuf:"varint,4,opt,name=compression,proto3,enum=protocol.Compression" json:"compression,omitempty"`
CertName string `protobuf:"bytes,5,opt,name=cert_name,json=certName,proto3" json:"cert_name,omitempty"`
MaxSequence int64 `protobuf:"varint,6,opt,name=max_sequence,json=maxSequence,proto3" json:"max_sequence,omitempty"`
Introducer bool `protobuf:"varint,7,opt,name=introducer,proto3" json:"introducer,omitempty"`
IndexID IndexID `protobuf:"varint,8,opt,name=index_id,json=indexId,proto3,customtype=IndexID" json:"index_id"`
ID DeviceID `protobuf:"bytes,1,opt,name=id,proto3,customtype=DeviceID" json:"id"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Addresses []string `protobuf:"bytes,3,rep,name=addresses" json:"addresses,omitempty"`
Compression Compression `protobuf:"varint,4,opt,name=compression,proto3,enum=protocol.Compression" json:"compression,omitempty"`
CertName string `protobuf:"bytes,5,opt,name=cert_name,json=certName,proto3" json:"cert_name,omitempty"`
MaxSequence int64 `protobuf:"varint,6,opt,name=max_sequence,json=maxSequence,proto3" json:"max_sequence,omitempty"`
Introducer bool `protobuf:"varint,7,opt,name=introducer,proto3" json:"introducer,omitempty"`
IndexID IndexID `protobuf:"varint,8,opt,name=index_id,json=indexId,proto3,customtype=IndexID" json:"index_id"`
SkipIntroductionRemovals bool `protobuf:"varint,9,opt,name=skip_introduction_removals,json=skipIntroductionRemovals,proto3" json:"skip_introduction_removals,omitempty"`
}
func (m *Device) Reset() { *m = Device{} }
@ -681,6 +682,16 @@ func (m *Device) MarshalTo(data []byte) (int, error) {
i++
i = encodeVarintBep(data, i, uint64(m.IndexID))
}
if m.SkipIntroductionRemovals {
data[i] = 0x48
i++
if m.SkipIntroductionRemovals {
data[i] = 1
} else {
data[i] = 0
}
i++
}
return i, nil
}
@ -1303,6 +1314,9 @@ func (m *Device) ProtoSize() (n int) {
if m.IndexID != 0 {
n += 1 + sovBep(uint64(m.IndexID))
}
if m.SkipIntroductionRemovals {
n += 2
}
return n
}
@ -2282,6 +2296,26 @@ func (m *Device) Unmarshal(data []byte) error {
break
}
}
case 9:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field SkipIntroductionRemovals", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowBep
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
v |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.SkipIntroductionRemovals = bool(v != 0)
default:
iNdEx = preIndex
skippy, err := skipBep(data[iNdEx:])
@ -3953,108 +3987,110 @@ var (
)
var fileDescriptorBep = []byte{
// 1635 bytes of a gzipped FileDescriptorProto
// 1665 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x73, 0xdb, 0xc6,
0x15, 0x17, 0x48, 0x10, 0x24, 0x1f, 0x29, 0x05, 0x5a, 0xcb, 0x0a, 0x0b, 0x2b, 0x14, 0x02, 0xc7,
0xad, 0xa2, 0x69, 0x14, 0x37, 0x4e, 0x9b, 0x99, 0xce, 0xb4, 0x33, 0x14, 0x09, 0xc9, 0x9c, 0xd0,
0x20, 0xb3, 0xa4, 0xec, 0x3a, 0x87, 0x62, 0x40, 0x62, 0x49, 0x61, 0x0c, 0x62, 0x59, 0x00, 0x94,
0xad, 0x7e, 0x04, 0xf6, 0x0b, 0xf4, 0xc2, 0x99, 0x4c, 0x6f, 0xbd, 0x76, 0xfa, 0x21, 0x7c, 0xcc,
0xe4, 0xd8, 0x83, 0xa7, 0x51, 0x2f, 0xfd, 0x02, 0xbd, 0x77, 0xb0, 0x0b, 0x80, 0xa0, 0xfe, 0x74,
0x7c, 0xe8, 0x89, 0xbb, 0xef, 0xfd, 0xf6, 0xed, 0xbe, 0xdf, 0xfb, 0xbd, 0x07, 0x42, 0x79, 0x48,
0x66, 0x47, 0x33, 0x9f, 0x86, 0x14, 0x95, 0xd8, 0xcf, 0x88, 0xba, 0xca, 0x67, 0x13, 0x27, 0x3c,
0x9f, 0x0f, 0x8f, 0x46, 0x74, 0xfa, 0xf9, 0x84, 0x4e, 0xe8, 0xe7, 0xcc, 0x33, 0x9c, 0x8f, 0xd9,
0x8e, 0x6d, 0xd8, 0x8a, 0x1f, 0xd4, 0x66, 0x50, 0x78, 0x4a, 0x5c, 0x97, 0xa2, 0x7d, 0xa8, 0xd8,
0xe4, 0xc2, 0x19, 0x11, 0xd3, 0xb3, 0xa6, 0xa4, 0x26, 0xa8, 0xc2, 0x41, 0x19, 0x03, 0x37, 0x19,
0xd6, 0x94, 0x44, 0x80, 0x91, 0xeb, 0x10, 0x2f, 0xe4, 0x80, 0x1c, 0x07, 0x70, 0x13, 0x03, 0x3c,
0x82, 0xad, 0x18, 0x70, 0x41, 0xfc, 0xc0, 0xa1, 0x5e, 0x2d, 0xcf, 0x30, 0x9b, 0xdc, 0xfa, 0x9c,
0x1b, 0xb5, 0x00, 0xa4, 0xa7, 0xc4, 0xb2, 0x89, 0x8f, 0x3e, 0x05, 0x31, 0xbc, 0x9c, 0xf1, 0xbb,
0xb6, 0xbe, 0xb8, 0x7f, 0x94, 0xe4, 0x70, 0xf4, 0x8c, 0x04, 0x81, 0x35, 0x21, 0x83, 0xcb, 0x19,
0xc1, 0x0c, 0x82, 0x7e, 0x0b, 0x95, 0x11, 0x9d, 0xce, 0x7c, 0x12, 0xb0, 0xc0, 0x39, 0x76, 0x62,
0xef, 0xc6, 0x89, 0xe6, 0x0a, 0x83, 0xb3, 0x07, 0xb4, 0x06, 0x6c, 0x36, 0xdd, 0x79, 0x10, 0x12,
0xbf, 0x49, 0xbd, 0xb1, 0x33, 0x41, 0x8f, 0xa1, 0x38, 0xa6, 0xae, 0x4d, 0xfc, 0xa0, 0x26, 0xa8,
0xf9, 0x83, 0xca, 0x17, 0xf2, 0x2a, 0xd8, 0x09, 0x73, 0x1c, 0x8b, 0x6f, 0xdf, 0xed, 0x6f, 0xe0,
0x04, 0xa6, 0xfd, 0x29, 0x07, 0x12, 0xf7, 0xa0, 0x5d, 0xc8, 0x39, 0x36, 0xa7, 0xe8, 0x58, 0xba,
0x7a, 0xb7, 0x9f, 0x6b, 0xb7, 0x70, 0xce, 0xb1, 0xd1, 0x0e, 0x14, 0x5c, 0x6b, 0x48, 0xdc, 0x98,
0x1c, 0xbe, 0x41, 0x0f, 0xa0, 0xec, 0x13, 0xcb, 0x36, 0xa9, 0xe7, 0x5e, 0x32, 0x4a, 0x4a, 0xb8,
0x14, 0x19, 0xba, 0x9e, 0x7b, 0x89, 0x3e, 0x03, 0xe4, 0x4c, 0x3c, 0xea, 0x13, 0x73, 0x46, 0xfc,
0xa9, 0xc3, 0x5e, 0x1b, 0xd4, 0x44, 0x86, 0xda, 0xe6, 0x9e, 0xde, 0xca, 0x81, 0x1e, 0xc2, 0x66,
0x0c, 0xb7, 0x89, 0x4b, 0x42, 0x52, 0x2b, 0x30, 0x64, 0x95, 0x1b, 0x5b, 0xcc, 0x86, 0x1e, 0xc3,
0x8e, 0xed, 0x04, 0xd6, 0xd0, 0x25, 0x66, 0x48, 0xa6, 0x33, 0xd3, 0xf1, 0x6c, 0xf2, 0x86, 0x04,
0x35, 0x89, 0x61, 0x51, 0xec, 0x1b, 0x90, 0xe9, 0xac, 0xcd, 0x3d, 0x11, 0x1b, 0xbc, 0xd2, 0x41,
0x4d, 0xbe, 0xce, 0x46, 0x8b, 0x39, 0x12, 0x36, 0x62, 0x98, 0xf6, 0xb7, 0x1c, 0x48, 0xdc, 0x83,
0x7e, 0x9a, 0xb2, 0x51, 0x3d, 0xde, 0x8d, 0x50, 0xff, 0x78, 0xb7, 0x5f, 0xe2, 0xbe, 0x76, 0x2b,
0xc3, 0x0e, 0x02, 0x31, 0xa3, 0x1c, 0xb6, 0x46, 0x7b, 0x50, 0xb6, 0x6c, 0x3b, 0xaa, 0x12, 0x09,
0x6a, 0x79, 0x35, 0x7f, 0x50, 0xc6, 0x2b, 0x03, 0xfa, 0x6a, 0xbd, 0xea, 0xe2, 0x75, 0x9d, 0xdc,
0x55, 0xee, 0x88, 0xf2, 0x11, 0xf1, 0x63, 0xa5, 0x16, 0xd8, 0x7d, 0xa5, 0xc8, 0xc0, 0x74, 0xfa,
0x31, 0x54, 0xa7, 0xd6, 0x1b, 0x33, 0x20, 0x7f, 0x98, 0x13, 0x6f, 0x44, 0x18, 0x2d, 0x79, 0x5c,
0x99, 0x5a, 0x6f, 0xfa, 0xb1, 0x09, 0xd5, 0x01, 0x1c, 0x2f, 0xf4, 0xa9, 0x3d, 0x1f, 0x11, 0xbf,
0x56, 0x64, 0xbc, 0x65, 0x2c, 0xe8, 0x97, 0x50, 0x62, 0xa4, 0x9a, 0x8e, 0x5d, 0x2b, 0xa9, 0xc2,
0x81, 0x78, 0xac, 0xc4, 0x89, 0x17, 0x19, 0xa5, 0x2c, 0xef, 0x64, 0x89, 0x8b, 0x0c, 0xdb, 0xb6,
0xb5, 0x2e, 0x14, 0x98, 0x0d, 0xed, 0x82, 0xc4, 0x65, 0x15, 0xf7, 0x59, 0xbc, 0x43, 0x47, 0x50,
0x18, 0x3b, 0x2e, 0x09, 0x6a, 0x39, 0x56, 0x05, 0x94, 0xd1, 0xa4, 0xe3, 0x92, 0xb6, 0x37, 0xa6,
0x71, 0x1d, 0x38, 0x4c, 0x3b, 0x83, 0x0a, 0x0b, 0x78, 0x36, 0xb3, 0xad, 0x90, 0xfc, 0xdf, 0xc2,
0xfe, 0x25, 0x0f, 0xa5, 0xc4, 0x93, 0x96, 0x4d, 0xc8, 0x94, 0xed, 0x30, 0xee, 0x5c, 0xde, 0x87,
0xbb, 0x37, 0xe3, 0x65, 0x5a, 0x17, 0x81, 0x18, 0x38, 0x7f, 0x24, 0x4c, 0xf9, 0x79, 0xcc, 0xd6,
0x48, 0x85, 0xca, 0x75, 0xb9, 0x6f, 0xe2, 0xac, 0x09, 0x7d, 0x04, 0x30, 0xa5, 0xb6, 0x33, 0x76,
0x88, 0x6d, 0x06, 0xac, 0x84, 0x79, 0x5c, 0x4e, 0x2c, 0x7d, 0x54, 0x8b, 0x04, 0x1b, 0x89, 0xdd,
0x8e, 0x55, 0x9d, 0x6c, 0x23, 0x8f, 0xe3, 0x5d, 0x58, 0xae, 0x63, 0xc7, 0x75, 0x4b, 0xb6, 0xd1,
0x7c, 0xf2, 0xe8, 0x5a, 0x9b, 0x95, 0x18, 0x60, 0xd3, 0xa3, 0xd9, 0x16, 0x7b, 0x0c, 0xc5, 0x64,
0x7e, 0x95, 0x55, 0x61, 0xbd, 0x17, 0x9e, 0x93, 0x51, 0x48, 0xd3, 0xc9, 0x10, 0xc3, 0x90, 0x02,
0xa5, 0x54, 0x4c, 0xc0, 0x5e, 0x9a, 0xee, 0xa3, 0xa9, 0x99, 0xe6, 0xe1, 0x05, 0xb5, 0x8a, 0x2a,
0x1c, 0x14, 0x70, 0x9a, 0x9a, 0x11, 0xa0, 0x5f, 0x80, 0x74, 0xec, 0xd2, 0xd1, 0xab, 0xa4, 0xf3,
0xee, 0xad, 0x6e, 0x63, 0xf6, 0x4c, 0x75, 0xa4, 0x21, 0x03, 0xfe, 0x5a, 0xfc, 0xf3, 0x77, 0xfb,
0x1b, 0xda, 0x37, 0x50, 0x4e, 0x01, 0x51, 0xe5, 0xe9, 0x78, 0x1c, 0x90, 0x90, 0x95, 0x29, 0x8f,
0xe3, 0x5d, 0x4a, 0x7e, 0x8e, 0xdd, 0xcb, 0xc9, 0x47, 0x20, 0x9e, 0x5b, 0xc1, 0x39, 0x2b, 0x48,
0x15, 0xb3, 0x75, 0x1c, 0xf2, 0x37, 0x20, 0xf1, 0x0c, 0xd1, 0x13, 0x28, 0x8d, 0xe8, 0xdc, 0x0b,
0x57, 0xf3, 0x71, 0x3b, 0xdb, 0x76, 0xcc, 0x13, 0xbf, 0x2a, 0x05, 0x6a, 0x27, 0x50, 0x8c, 0x5d,
0xe8, 0x51, 0x3a, 0x13, 0xc4, 0xe3, 0xfb, 0x49, 0x6b, 0xf4, 0xcf, 0xa9, 0x1f, 0xae, 0x8d, 0x84,
0x1d, 0x28, 0x5c, 0x58, 0xee, 0x9c, 0xbf, 0x4f, 0xc4, 0x7c, 0xa3, 0xfd, 0x5d, 0x80, 0x22, 0x8e,
0x08, 0x0c, 0xc2, 0xcc, 0xa8, 0x2d, 0xac, 0x8d, 0xda, 0x95, 0xd4, 0x73, 0x6b, 0x52, 0x4f, 0xd4,
0x9a, 0xcf, 0xa8, 0x75, 0x45, 0x8e, 0x78, 0x2b, 0x39, 0x85, 0x5b, 0xc8, 0x91, 0x56, 0xe4, 0x44,
0xc2, 0x19, 0xfb, 0x74, 0xca, 0x86, 0x29, 0xf5, 0x2d, 0xff, 0x32, 0x56, 0xd6, 0x66, 0x64, 0x1d,
0x24, 0x46, 0xcd, 0x84, 0x12, 0x26, 0xc1, 0x8c, 0x7a, 0x01, 0xb9, 0xf3, 0xd9, 0x08, 0x44, 0xdb,
0x0a, 0x2d, 0xf6, 0xe8, 0x2a, 0x66, 0x6b, 0xf4, 0x33, 0x10, 0x47, 0xd4, 0xe6, 0x4f, 0xde, 0xca,
0xd6, 0x5f, 0xf7, 0x7d, 0xea, 0x37, 0xa9, 0x4d, 0x30, 0x03, 0x68, 0x33, 0x90, 0x5b, 0xf4, 0xb5,
0xe7, 0x52, 0xcb, 0xee, 0xf9, 0x74, 0x12, 0x0d, 0xbb, 0x3b, 0x5b, 0xbe, 0x05, 0xc5, 0x39, 0x1b,
0x0a, 0x49, 0xd3, 0x7f, 0xb2, 0xde, 0xa4, 0xd7, 0x03, 0xf1, 0x09, 0x92, 0x28, 0x3b, 0x3e, 0xaa,
0xfd, 0x20, 0x80, 0x72, 0x37, 0x1a, 0xb5, 0xa1, 0xc2, 0x91, 0x66, 0xe6, 0x3b, 0x7e, 0xf0, 0x3e,
0x17, 0xb1, 0xf9, 0x00, 0xf3, 0x74, 0x7d, 0xeb, 0xc7, 0x21, 0xd3, 0x89, 0xf9, 0xf7, 0xeb, 0xc4,
0x87, 0xb0, 0xc9, 0x7a, 0x24, 0xfd, 0xe4, 0x89, 0x6a, 0xfe, 0xa0, 0x80, 0xab, 0x43, 0xde, 0x28,
0xcc, 0xa6, 0x49, 0x20, 0xf6, 0x1c, 0x6f, 0xa2, 0xed, 0x43, 0xa1, 0xe9, 0x52, 0x56, 0x2c, 0xc9,
0x27, 0x56, 0x40, 0xbd, 0x84, 0x43, 0xbe, 0x3b, 0xfc, 0x21, 0x07, 0x95, 0xcc, 0x5f, 0x11, 0xf4,
0x18, 0xb6, 0x9a, 0x9d, 0xb3, 0xfe, 0x40, 0xc7, 0x66, 0xb3, 0x6b, 0x9c, 0xb4, 0x4f, 0xe5, 0x0d,
0x65, 0x6f, 0xb1, 0x54, 0x6b, 0xd3, 0x15, 0x68, 0xfd, 0x5f, 0xc6, 0x3e, 0x14, 0xda, 0x46, 0x4b,
0xff, 0x9d, 0x2c, 0x28, 0x3b, 0x8b, 0xa5, 0x2a, 0x67, 0x80, 0xfc, 0x43, 0xf0, 0x73, 0xa8, 0x32,
0x80, 0x79, 0xd6, 0x6b, 0x35, 0x06, 0xba, 0x9c, 0x53, 0x94, 0xc5, 0x52, 0xdd, 0xbd, 0x8e, 0x8b,
0xf9, 0x7e, 0x08, 0x45, 0xac, 0x7f, 0x73, 0xa6, 0xf7, 0x07, 0x72, 0x5e, 0xd9, 0x5d, 0x2c, 0x55,
0x94, 0x01, 0x26, 0x1d, 0xf3, 0x08, 0x4a, 0x58, 0xef, 0xf7, 0xba, 0x46, 0x5f, 0x97, 0x45, 0xe5,
0xc3, 0xc5, 0x52, 0xbd, 0xb7, 0x86, 0x8a, 0x15, 0xfa, 0x2b, 0xd8, 0x6e, 0x75, 0x5f, 0x18, 0x9d,
0x6e, 0xa3, 0x65, 0xf6, 0x70, 0xf7, 0x14, 0xeb, 0xfd, 0xbe, 0x5c, 0x50, 0xf6, 0x17, 0x4b, 0xf5,
0x41, 0x06, 0x7f, 0x43, 0x70, 0x1f, 0x81, 0xd8, 0x6b, 0x1b, 0xa7, 0xb2, 0xa4, 0xdc, 0x5b, 0x2c,
0xd5, 0x0f, 0x32, 0xd0, 0x88, 0xd4, 0x28, 0xe3, 0x66, 0xa7, 0xdb, 0xd7, 0xe5, 0xe2, 0x8d, 0x8c,
0x19, 0xd9, 0x87, 0xbf, 0x07, 0x74, 0xf3, 0xcf, 0x1a, 0xfa, 0x04, 0x44, 0xa3, 0x6b, 0xe8, 0xf2,
0x06, 0xcf, 0xff, 0x26, 0xc2, 0xa0, 0x1e, 0x41, 0x1a, 0xe4, 0x3b, 0xdf, 0x7e, 0x29, 0x0b, 0xca,
0x4f, 0x16, 0x4b, 0xf5, 0xfe, 0x4d, 0x50, 0xe7, 0xdb, 0x2f, 0x0f, 0x29, 0x54, 0xb2, 0x81, 0x35,
0x28, 0x3d, 0xd3, 0x07, 0x8d, 0x56, 0x63, 0xd0, 0x90, 0x37, 0xf8, 0x93, 0x12, 0xf7, 0x33, 0x12,
0x5a, 0xac, 0x01, 0xf7, 0xa0, 0x60, 0xe8, 0xcf, 0x75, 0x2c, 0x0b, 0xca, 0xf6, 0x62, 0xa9, 0x6e,
0x26, 0x00, 0x83, 0x5c, 0x10, 0x1f, 0xd5, 0x41, 0x6a, 0x74, 0x5e, 0x34, 0x5e, 0xf6, 0xe5, 0x9c,
0x82, 0x16, 0x4b, 0x75, 0x2b, 0x71, 0x37, 0xdc, 0xd7, 0xd6, 0x65, 0x70, 0xf8, 0x1f, 0x01, 0xaa,
0xd9, 0xcf, 0x1e, 0xaa, 0x83, 0x78, 0xd2, 0xee, 0xe8, 0xc9, 0x75, 0x59, 0x5f, 0xb4, 0x46, 0x07,
0x50, 0x6e, 0xb5, 0xb1, 0xde, 0x1c, 0x74, 0xf1, 0xcb, 0x24, 0x97, 0x2c, 0xa8, 0xe5, 0xf8, 0x4c,
0xdc, 0xd1, 0x9f, 0xc3, 0x6a, 0xff, 0xe5, 0xb3, 0x4e, 0xdb, 0xf8, 0xda, 0x64, 0x11, 0x73, 0xca,
0x83, 0xc5, 0x52, 0xfd, 0x30, 0x0b, 0xee, 0x5f, 0x4e, 0x5d, 0xc7, 0x7b, 0xc5, 0x02, 0x7f, 0x05,
0xdb, 0x09, 0x7c, 0x75, 0x41, 0x5e, 0x51, 0x17, 0x4b, 0x75, 0xef, 0x96, 0x33, 0xab, 0x7b, 0x9e,
0xc0, 0x07, 0xc9, 0xc1, 0x33, 0xe3, 0x6b, 0xa3, 0xfb, 0xc2, 0x90, 0x45, 0xa5, 0xbe, 0x58, 0xaa,
0xca, 0x2d, 0xc7, 0xce, 0xbc, 0x57, 0x1e, 0x7d, 0xed, 0x1d, 0xfe, 0x55, 0x80, 0x72, 0x3a, 0xa1,
0x22, 0x9e, 0x8d, 0xae, 0xa9, 0x63, 0xdc, 0xc5, 0x49, 0xe2, 0xa9, 0xd3, 0xa0, 0x6c, 0x89, 0x3e,
0x86, 0xe2, 0xa9, 0x6e, 0xe8, 0xb8, 0xdd, 0x4c, 0xfa, 0x21, 0x85, 0x9c, 0x12, 0x8f, 0xf8, 0xce,
0x08, 0x7d, 0x0a, 0x55, 0xa3, 0x6b, 0xf6, 0xcf, 0x9a, 0x4f, 0x93, 0x8c, 0x99, 0x80, 0x33, 0xa1,
0xfa, 0xf3, 0xd1, 0x39, 0xcb, 0xf6, 0x30, 0x6a, 0x9d, 0xe7, 0x8d, 0x4e, 0xbb, 0xc5, 0xa1, 0x79,
0xa5, 0xb6, 0x58, 0xaa, 0x3b, 0x29, 0xb4, 0xcd, 0x3f, 0xfb, 0x11, 0xf6, 0xd0, 0x86, 0xfa, 0xff,
0x9e, 0x45, 0x48, 0x05, 0xa9, 0xd1, 0xeb, 0xe9, 0x46, 0x2b, 0x79, 0xfd, 0xca, 0xd7, 0x98, 0xcd,
0x88, 0x67, 0x47, 0x88, 0x93, 0x2e, 0x3e, 0xd5, 0x07, 0xc9, 0xe3, 0x57, 0x88, 0x13, 0xea, 0x4f,
0x48, 0x78, 0xbc, 0xf7, 0xf6, 0xc7, 0xfa, 0xc6, 0xf7, 0x3f, 0xd6, 0x37, 0xde, 0x5e, 0xd5, 0x85,
0xef, 0xaf, 0xea, 0xc2, 0x3f, 0xaf, 0xea, 0x1b, 0xff, 0xbe, 0xaa, 0x0b, 0xdf, 0xfd, 0xab, 0x2e,
0x0c, 0x25, 0x36, 0xbb, 0x9e, 0xfc, 0x37, 0x00, 0x00, 0xff, 0xff, 0x96, 0x0b, 0xf7, 0x15, 0xb6,
0x0d, 0x00, 0x00,
0x15, 0x17, 0x48, 0xf0, 0xdf, 0x23, 0xa5, 0x40, 0x6b, 0x59, 0x41, 0x61, 0x85, 0x42, 0xe0, 0xb8,
0x55, 0x34, 0x8d, 0xe2, 0xc6, 0x69, 0x33, 0xd3, 0x69, 0x3b, 0x43, 0x91, 0x90, 0xcc, 0x09, 0x0d,
0x32, 0x4b, 0xca, 0xae, 0x73, 0x28, 0x06, 0x24, 0x96, 0x14, 0xc6, 0x20, 0x96, 0x05, 0x40, 0xd9,
0xea, 0x47, 0x60, 0xbf, 0x40, 0x2f, 0x9c, 0xc9, 0xf4, 0xd6, 0x7b, 0x3f, 0x84, 0x8f, 0x99, 0x1c,
0x7b, 0xf0, 0x34, 0xea, 0xa5, 0xc7, 0x5e, 0x7a, 0xef, 0x60, 0x17, 0x00, 0x41, 0xfd, 0xe9, 0xe4,
0x90, 0x13, 0x77, 0xdf, 0xfb, 0xed, 0xdb, 0x7d, 0xbf, 0xf7, 0x7e, 0x8f, 0x80, 0xca, 0x90, 0xcc,
0x8e, 0x66, 0x3e, 0x0d, 0x29, 0x2a, 0xb3, 0x9f, 0x11, 0x75, 0x95, 0x4f, 0x26, 0x4e, 0x78, 0x3e,
0x1f, 0x1e, 0x8d, 0xe8, 0xf4, 0xd3, 0x09, 0x9d, 0xd0, 0x4f, 0x99, 0x67, 0x38, 0x1f, 0xb3, 0x1d,
0xdb, 0xb0, 0x15, 0x3f, 0xa8, 0xcd, 0xa0, 0xf0, 0x94, 0xb8, 0x2e, 0x45, 0xfb, 0x50, 0xb5, 0xc9,
0x85, 0x33, 0x22, 0xa6, 0x67, 0x4d, 0x89, 0x2c, 0xa8, 0xc2, 0x41, 0x05, 0x03, 0x37, 0x19, 0xd6,
0x94, 0x44, 0x80, 0x91, 0xeb, 0x10, 0x2f, 0xe4, 0x80, 0x1c, 0x07, 0x70, 0x13, 0x03, 0x3c, 0x82,
0xad, 0x18, 0x70, 0x41, 0xfc, 0xc0, 0xa1, 0x9e, 0x9c, 0x67, 0x98, 0x4d, 0x6e, 0x7d, 0xce, 0x8d,
0x5a, 0x00, 0xc5, 0xa7, 0xc4, 0xb2, 0x89, 0x8f, 0x3e, 0x06, 0x31, 0xbc, 0x9c, 0xf1, 0xbb, 0xb6,
0x3e, 0xbb, 0x7f, 0x94, 0xe4, 0x70, 0xf4, 0x8c, 0x04, 0x81, 0x35, 0x21, 0x83, 0xcb, 0x19, 0xc1,
0x0c, 0x82, 0x7e, 0x07, 0xd5, 0x11, 0x9d, 0xce, 0x7c, 0x12, 0xb0, 0xc0, 0x39, 0x76, 0x62, 0xef,
0xc6, 0x89, 0xe6, 0x0a, 0x83, 0xb3, 0x07, 0xb4, 0x06, 0x6c, 0x36, 0xdd, 0x79, 0x10, 0x12, 0xbf,
0x49, 0xbd, 0xb1, 0x33, 0x41, 0x8f, 0xa1, 0x34, 0xa6, 0xae, 0x4d, 0xfc, 0x40, 0x16, 0xd4, 0xfc,
0x41, 0xf5, 0x33, 0x69, 0x15, 0xec, 0x84, 0x39, 0x8e, 0xc5, 0xb7, 0xef, 0xf6, 0x37, 0x70, 0x02,
0xd3, 0xfe, 0x9c, 0x83, 0x22, 0xf7, 0xa0, 0x5d, 0xc8, 0x39, 0x36, 0xa7, 0xe8, 0xb8, 0x78, 0xf5,
0x6e, 0x3f, 0xd7, 0x6e, 0xe1, 0x9c, 0x63, 0xa3, 0x1d, 0x28, 0xb8, 0xd6, 0x90, 0xb8, 0x31, 0x39,
0x7c, 0x83, 0x1e, 0x40, 0xc5, 0x27, 0x96, 0x6d, 0x52, 0xcf, 0xbd, 0x64, 0x94, 0x94, 0x71, 0x39,
0x32, 0x74, 0x3d, 0xf7, 0x12, 0x7d, 0x02, 0xc8, 0x99, 0x78, 0xd4, 0x27, 0xe6, 0x8c, 0xf8, 0x53,
0x87, 0xbd, 0x36, 0x90, 0x45, 0x86, 0xda, 0xe6, 0x9e, 0xde, 0xca, 0x81, 0x1e, 0xc2, 0x66, 0x0c,
0xb7, 0x89, 0x4b, 0x42, 0x22, 0x17, 0x18, 0xb2, 0xc6, 0x8d, 0x2d, 0x66, 0x43, 0x8f, 0x61, 0xc7,
0x76, 0x02, 0x6b, 0xe8, 0x12, 0x33, 0x24, 0xd3, 0x99, 0xe9, 0x78, 0x36, 0x79, 0x43, 0x02, 0xb9,
0xc8, 0xb0, 0x28, 0xf6, 0x0d, 0xc8, 0x74, 0xd6, 0xe6, 0x9e, 0x88, 0x0d, 0x5e, 0xe9, 0x40, 0x96,
0xae, 0xb3, 0xd1, 0x62, 0x8e, 0x84, 0x8d, 0x18, 0xa6, 0xfd, 0x27, 0x07, 0x45, 0xee, 0x41, 0x3f,
0x4d, 0xd9, 0xa8, 0x1d, 0xef, 0x46, 0xa8, 0x7f, 0xbc, 0xdb, 0x2f, 0x73, 0x5f, 0xbb, 0x95, 0x61,
0x07, 0x81, 0x98, 0xe9, 0x1c, 0xb6, 0x46, 0x7b, 0x50, 0xb1, 0x6c, 0x3b, 0xaa, 0x12, 0x09, 0xe4,
0xbc, 0x9a, 0x3f, 0xa8, 0xe0, 0x95, 0x01, 0x7d, 0xb1, 0x5e, 0x75, 0xf1, 0x7a, 0x9f, 0xdc, 0x55,
0xee, 0x88, 0xf2, 0x11, 0xf1, 0xe3, 0x4e, 0x2d, 0xb0, 0xfb, 0xca, 0x91, 0x81, 0xf5, 0xe9, 0x87,
0x50, 0x9b, 0x5a, 0x6f, 0xcc, 0x80, 0xfc, 0x71, 0x4e, 0xbc, 0x11, 0x61, 0xb4, 0xe4, 0x71, 0x75,
0x6a, 0xbd, 0xe9, 0xc7, 0x26, 0x54, 0x07, 0x70, 0xbc, 0xd0, 0xa7, 0xf6, 0x7c, 0x44, 0x7c, 0xb9,
0xc4, 0x78, 0xcb, 0x58, 0xd0, 0x2f, 0xa1, 0xcc, 0x48, 0x35, 0x1d, 0x5b, 0x2e, 0xab, 0xc2, 0x81,
0x78, 0xac, 0xc4, 0x89, 0x97, 0x18, 0xa5, 0x2c, 0xef, 0x64, 0x89, 0x4b, 0x0c, 0xdb, 0xb6, 0xd1,
0x6f, 0x40, 0x09, 0x5e, 0x39, 0x51, 0x41, 0x78, 0xa4, 0xd0, 0xa1, 0x9e, 0xe9, 0x93, 0x29, 0xbd,
0xb0, 0xdc, 0x40, 0xae, 0xb0, 0x6b, 0xe4, 0x08, 0xd1, 0xce, 0x00, 0x70, 0xec, 0xd7, 0xba, 0x50,
0x60, 0x11, 0xd1, 0x2e, 0x14, 0x79, 0x53, 0xc6, 0x2a, 0x8d, 0x77, 0xe8, 0x08, 0x0a, 0x63, 0xc7,
0x25, 0x81, 0x9c, 0x63, 0x35, 0x44, 0x99, 0x8e, 0x76, 0x5c, 0xd2, 0xf6, 0xc6, 0x34, 0xae, 0x22,
0x87, 0x69, 0x67, 0x50, 0x65, 0x01, 0xcf, 0x66, 0xb6, 0x15, 0x92, 0x1f, 0x2d, 0xec, 0x5f, 0xf3,
0x50, 0x4e, 0x3c, 0x69, 0xd1, 0x85, 0x4c, 0xd1, 0x0f, 0x63, 0xdd, 0x73, 0x15, 0xef, 0xde, 0x8c,
0x97, 0x11, 0x3e, 0x02, 0x31, 0x70, 0xfe, 0x44, 0x98, 0x6e, 0xf2, 0x98, 0xad, 0x91, 0x0a, 0xd5,
0xeb, 0x62, 0xd9, 0xc4, 0x59, 0x13, 0xfa, 0x00, 0x60, 0x4a, 0x6d, 0x67, 0xec, 0x10, 0xdb, 0x0c,
0x58, 0x03, 0xe4, 0x71, 0x25, 0xb1, 0xf4, 0x91, 0x1c, 0xb5, 0x7b, 0x24, 0x15, 0x3b, 0xd6, 0x44,
0xb2, 0x8d, 0x3c, 0x8e, 0x77, 0x61, 0xb9, 0x8e, 0x1d, 0x57, 0x3d, 0xd9, 0x46, 0xd3, 0xcd, 0xa3,
0x6b, 0x22, 0x2d, 0x33, 0xc0, 0xa6, 0x47, 0xb3, 0x02, 0x7d, 0x0c, 0xa5, 0x64, 0xfa, 0x45, 0xf5,
0x5c, 0x53, 0xd2, 0x73, 0x32, 0x0a, 0x69, 0x3a, 0x57, 0x62, 0x18, 0x52, 0xa0, 0x9c, 0xb6, 0x22,
0xb0, 0x97, 0xa6, 0xfb, 0x68, 0xe6, 0xa6, 0x79, 0x78, 0x81, 0x5c, 0x55, 0x85, 0x83, 0x02, 0x4e,
0x53, 0x33, 0x02, 0xf4, 0x0b, 0x28, 0x1e, 0xbb, 0x74, 0xf4, 0x2a, 0xd1, 0xed, 0xbd, 0xd5, 0x6d,
0xcc, 0x9e, 0xa9, 0x4e, 0x71, 0xc8, 0x80, 0xbf, 0x16, 0xff, 0xf2, 0xcd, 0xfe, 0x86, 0xf6, 0x15,
0x54, 0x52, 0x40, 0x54, 0x79, 0x3a, 0x1e, 0x07, 0x24, 0x64, 0x65, 0xca, 0xe3, 0x78, 0x97, 0x92,
0x9f, 0x63, 0xf7, 0x72, 0xf2, 0x11, 0x88, 0xe7, 0x56, 0x70, 0xce, 0x0a, 0x52, 0xc3, 0x6c, 0x1d,
0x87, 0xfc, 0x2d, 0x14, 0x79, 0x86, 0xe8, 0x09, 0x94, 0x47, 0x74, 0xee, 0x85, 0xab, 0xe9, 0xba,
0x9d, 0x15, 0x2d, 0xf3, 0xc4, 0xaf, 0x4a, 0x81, 0xda, 0x09, 0x94, 0x62, 0x17, 0x7a, 0x94, 0x4e,
0x14, 0xf1, 0xf8, 0x7e, 0x22, 0xac, 0xfe, 0x39, 0xf5, 0xc3, 0xb5, 0x81, 0xb2, 0x03, 0x85, 0x0b,
0xcb, 0x9d, 0xf3, 0xf7, 0x89, 0x98, 0x6f, 0xb4, 0xbf, 0x0b, 0x50, 0xc2, 0x11, 0x81, 0x41, 0x98,
0x19, 0xd4, 0x85, 0xb5, 0x41, 0xbd, 0x6a, 0xf5, 0xdc, 0x5a, 0xab, 0x27, 0xdd, 0x9a, 0xcf, 0x74,
0xeb, 0x8a, 0x1c, 0xf1, 0x56, 0x72, 0x0a, 0xb7, 0x90, 0x53, 0x5c, 0x91, 0x13, 0x35, 0xce, 0xd8,
0xa7, 0x53, 0x36, 0x8a, 0xa9, 0x6f, 0xf9, 0x97, 0x71, 0x67, 0x6d, 0x46, 0xd6, 0x41, 0x62, 0xd4,
0x4c, 0x28, 0x63, 0x12, 0xcc, 0xa8, 0x17, 0x90, 0x3b, 0x9f, 0x8d, 0x40, 0xb4, 0xad, 0xd0, 0x62,
0x8f, 0xae, 0x61, 0xb6, 0x46, 0x3f, 0x03, 0x71, 0x44, 0x6d, 0xfe, 0xe4, 0xad, 0x6c, 0xfd, 0x75,
0xdf, 0xa7, 0x7e, 0x93, 0xda, 0x04, 0x33, 0x80, 0x36, 0x03, 0xa9, 0x45, 0x5f, 0x7b, 0x2e, 0xb5,
0xec, 0x9e, 0x4f, 0x27, 0xd1, 0xa8, 0xbc, 0x53, 0xf2, 0x2d, 0x28, 0xcd, 0xd9, 0x50, 0x48, 0x44,
0xff, 0xd1, 0xba, 0x48, 0xaf, 0x07, 0xe2, 0x13, 0x24, 0xe9, 0xec, 0xf8, 0xa8, 0xf6, 0x9d, 0x00,
0xca, 0xdd, 0x68, 0xd4, 0x86, 0x2a, 0x47, 0x9a, 0x99, 0xaf, 0x80, 0x83, 0x1f, 0x72, 0x11, 0x9b,
0x0f, 0x30, 0x4f, 0xd7, 0xb7, 0xfe, 0xb5, 0x64, 0x94, 0x98, 0xff, 0x61, 0x4a, 0x7c, 0x08, 0x9b,
0x4c, 0x23, 0xe9, 0x1f, 0xa6, 0xa8, 0xe6, 0x0f, 0x0a, 0xb8, 0x36, 0xe4, 0x42, 0x61, 0x36, 0xad,
0x08, 0x62, 0xcf, 0xf1, 0x26, 0xda, 0x3e, 0x14, 0x9a, 0x2e, 0x65, 0xc5, 0x2a, 0xfa, 0xc4, 0x0a,
0xa8, 0x97, 0x70, 0xc8, 0x77, 0x87, 0xdf, 0xe5, 0xa0, 0x9a, 0xf9, 0x90, 0x41, 0x8f, 0x61, 0xab,
0xd9, 0x39, 0xeb, 0x0f, 0x74, 0x6c, 0x36, 0xbb, 0xc6, 0x49, 0xfb, 0x54, 0xda, 0x50, 0xf6, 0x16,
0x4b, 0x55, 0x9e, 0xae, 0x40, 0xeb, 0xdf, 0x28, 0xfb, 0x50, 0x68, 0x1b, 0x2d, 0xfd, 0xf7, 0x92,
0xa0, 0xec, 0x2c, 0x96, 0xaa, 0x94, 0x01, 0xf2, 0x3f, 0x82, 0x9f, 0x43, 0x8d, 0x01, 0xcc, 0xb3,
0x5e, 0xab, 0x31, 0xd0, 0xa5, 0x9c, 0xa2, 0x2c, 0x96, 0xea, 0xee, 0x75, 0x5c, 0xcc, 0xf7, 0x43,
0x28, 0x61, 0xfd, 0xab, 0x33, 0xbd, 0x3f, 0x90, 0xf2, 0xca, 0xee, 0x62, 0xa9, 0xa2, 0x0c, 0x30,
0x51, 0xcc, 0x23, 0x28, 0x63, 0xbd, 0xdf, 0xeb, 0x1a, 0x7d, 0x5d, 0x12, 0x95, 0xf7, 0x17, 0x4b,
0xf5, 0xde, 0x1a, 0x2a, 0xee, 0xd0, 0x5f, 0xc1, 0x76, 0xab, 0xfb, 0xc2, 0xe8, 0x74, 0x1b, 0x2d,
0xb3, 0x87, 0xbb, 0xa7, 0x58, 0xef, 0xf7, 0xa5, 0x82, 0xb2, 0xbf, 0x58, 0xaa, 0x0f, 0x32, 0xf8,
0x1b, 0x0d, 0xf7, 0x01, 0x88, 0xbd, 0xb6, 0x71, 0x2a, 0x15, 0x95, 0x7b, 0x8b, 0xa5, 0xfa, 0x5e,
0x06, 0x1a, 0x91, 0x1a, 0x65, 0xdc, 0xec, 0x74, 0xfb, 0xba, 0x54, 0xba, 0x91, 0x31, 0x23, 0xfb,
0xf0, 0x0f, 0x80, 0x6e, 0x7e, 0xea, 0xa1, 0x8f, 0x40, 0x34, 0xba, 0x86, 0x2e, 0x6d, 0xf0, 0xfc,
0x6f, 0x22, 0x0c, 0xea, 0x11, 0xa4, 0x41, 0xbe, 0xf3, 0xf5, 0xe7, 0x92, 0xa0, 0xfc, 0x64, 0xb1,
0x54, 0xef, 0xdf, 0x04, 0x75, 0xbe, 0xfe, 0xfc, 0x90, 0x42, 0x35, 0x1b, 0x58, 0x83, 0xf2, 0x33,
0x7d, 0xd0, 0x68, 0x35, 0x06, 0x0d, 0x69, 0x83, 0x3f, 0x29, 0x71, 0x3f, 0x23, 0xa1, 0xc5, 0x04,
0xb8, 0x07, 0x05, 0x43, 0x7f, 0xae, 0x63, 0x49, 0x50, 0xb6, 0x17, 0x4b, 0x75, 0x33, 0x01, 0x18,
0xe4, 0x82, 0xf8, 0xa8, 0x0e, 0xc5, 0x46, 0xe7, 0x45, 0xe3, 0x65, 0x5f, 0xca, 0x29, 0x68, 0xb1,
0x54, 0xb7, 0x12, 0x77, 0xc3, 0x7d, 0x6d, 0x5d, 0x06, 0x87, 0xff, 0x15, 0xa0, 0x96, 0xfd, 0xdb,
0x43, 0x75, 0x10, 0x4f, 0xda, 0x1d, 0x3d, 0xb9, 0x2e, 0xeb, 0x8b, 0xd6, 0xe8, 0x00, 0x2a, 0xad,
0x36, 0xd6, 0x9b, 0x83, 0x2e, 0x7e, 0x99, 0xe4, 0x92, 0x05, 0xb5, 0x1c, 0x9f, 0x35, 0x77, 0xf4,
0x69, 0x59, 0xeb, 0xbf, 0x7c, 0xd6, 0x69, 0x1b, 0x5f, 0x9a, 0x2c, 0x62, 0x4e, 0x79, 0xb0, 0x58,
0xaa, 0xef, 0x67, 0xc1, 0xfd, 0xcb, 0xa9, 0xeb, 0x78, 0xaf, 0x58, 0xe0, 0x2f, 0x60, 0x3b, 0x81,
0xaf, 0x2e, 0xc8, 0x2b, 0xea, 0x62, 0xa9, 0xee, 0xdd, 0x72, 0x66, 0x75, 0xcf, 0x13, 0x78, 0x2f,
0x39, 0x78, 0x66, 0x7c, 0x69, 0x74, 0x5f, 0x18, 0x92, 0xa8, 0xd4, 0x17, 0x4b, 0x55, 0xb9, 0xe5,
0xd8, 0x99, 0xf7, 0xca, 0xa3, 0xaf, 0xbd, 0xc3, 0xbf, 0x09, 0x50, 0x49, 0x27, 0x54, 0xc4, 0xb3,
0xd1, 0x35, 0x75, 0x8c, 0xbb, 0x38, 0x49, 0x3c, 0x75, 0x1a, 0x94, 0x2d, 0xd1, 0x87, 0x50, 0x3a,
0xd5, 0x0d, 0x1d, 0xb7, 0x9b, 0x89, 0x1e, 0x52, 0xc8, 0x29, 0xf1, 0x88, 0xef, 0x8c, 0xd0, 0xc7,
0x50, 0x33, 0xba, 0x66, 0xff, 0xac, 0xf9, 0x34, 0xc9, 0x98, 0x35, 0x70, 0x26, 0x54, 0x7f, 0x3e,
0x3a, 0x67, 0xd9, 0x1e, 0x46, 0xd2, 0x79, 0xde, 0xe8, 0xb4, 0x5b, 0x1c, 0x9a, 0x57, 0xe4, 0xc5,
0x52, 0xdd, 0x49, 0xa1, 0x6d, 0xfe, 0xb7, 0x1f, 0x61, 0x0f, 0x6d, 0xa8, 0xff, 0xff, 0x59, 0x84,
0x54, 0x28, 0x36, 0x7a, 0x3d, 0xdd, 0x68, 0x25, 0xaf, 0x5f, 0xf9, 0x1a, 0xb3, 0x19, 0xf1, 0xec,
0x08, 0x71, 0xd2, 0xc5, 0xa7, 0xfa, 0x20, 0x79, 0xfc, 0x0a, 0x71, 0x42, 0xfd, 0x09, 0x09, 0x8f,
0xf7, 0xde, 0x7e, 0x5f, 0xdf, 0xf8, 0xf6, 0xfb, 0xfa, 0xc6, 0xdb, 0xab, 0xba, 0xf0, 0xed, 0x55,
0x5d, 0xf8, 0xe7, 0x55, 0x7d, 0xe3, 0xdf, 0x57, 0x75, 0xe1, 0x9b, 0x7f, 0xd5, 0x85, 0x61, 0x91,
0xcd, 0xae, 0x27, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x64, 0x17, 0x1e, 0x19, 0xf4, 0x0d, 0x00,
0x00,
}

View File

@ -63,14 +63,15 @@ message Folder {
}
message Device {
bytes id = 1 [(gogoproto.customname) = "ID", (gogoproto.customtype) = "DeviceID", (gogoproto.nullable) = false];
string name = 2;
repeated string addresses = 3;
Compression compression = 4;
string cert_name = 5;
int64 max_sequence = 6;
bool introducer = 7;
uint64 index_id = 8 [(gogoproto.customname) = "IndexID", (gogoproto.customtype) = "IndexID", (gogoproto.nullable) = false];
bytes id = 1 [(gogoproto.customname) = "ID", (gogoproto.customtype) = "DeviceID", (gogoproto.nullable) = false];
string name = 2;
repeated string addresses = 3;
Compression compression = 4;
string cert_name = 5;
int64 max_sequence = 6;
bool introducer = 7;
uint64 index_id = 8 [(gogoproto.customname) = "IndexID", (gogoproto.customtype) = "IndexID", (gogoproto.nullable) = false];
bool skip_introduction_removals = 9;
}
enum Compression {