From d6a0a44432ca4e38b8d66d91c146a8c3fe7649f4 Mon Sep 17 00:00:00 2001 From: Audrius Butkevicius Date: Wed, 7 Oct 2015 00:37:08 +0100 Subject: [PATCH 1/5] Update xdr --- Godeps/Godeps.json | 2 +- .../src/github.com/calmh/xdr/.travis.yml | 2 +- .../src/github.com/calmh/xdr/README.md | 2 +- .../github.com/calmh/xdr/cmd/genxdr/main.go | 37 +++++++++++++------ 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 16a6182c9..8439b0e29 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -19,7 +19,7 @@ }, { "ImportPath": "github.com/calmh/xdr", - "Rev": "5f7208e86762911861c94f1849eddbfc0a60cbf0" + "Rev": "47c0042d09a827b81ee62497f99e5e0c7f0bd31c" }, { "ImportPath": "github.com/golang/snappy", diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/.travis.yml b/Godeps/_workspace/src/github.com/calmh/xdr/.travis.yml index a7c4c07b3..0fccc9e32 100644 --- a/Godeps/_workspace/src/github.com/calmh/xdr/.travis.yml +++ b/Godeps/_workspace/src/github.com/calmh/xdr/.travis.yml @@ -4,7 +4,7 @@ go: install: - export PATH=$PATH:$HOME/gopath/bin -- go get code.google.com/p/go.tools/cmd/cover +- go get golang.org/x/tools/cover - go get github.com/mattn/goveralls script: diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/README.md b/Godeps/_workspace/src/github.com/calmh/xdr/README.md index dfc2e3f6b..f4ebae780 100644 --- a/Godeps/_workspace/src/github.com/calmh/xdr/README.md +++ b/Godeps/_workspace/src/github.com/calmh/xdr/README.md @@ -1,7 +1,7 @@ xdr === -[![Build Status](https://img.shields.io/travis/calmh/xdr.svg?style=flat)](https://travis-ci.org/calmh/xdr) +[![Build Status](https://img.shields.io/circleci/project/calmh/xdr.svg?style=flat-square)](https://circleci.com/gh/calmh/xdr) [![Coverage Status](https://img.shields.io/coveralls/calmh/xdr.svg?style=flat)](https://coveralls.io/r/calmh/xdr?branch=master) [![API Documentation](http://img.shields.io/badge/api-Godoc-blue.svg?style=flat)](http://godoc.org/github.com/calmh/xdr) [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](http://opensource.org/licenses/MIT) diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/cmd/genxdr/main.go b/Godeps/_workspace/src/github.com/calmh/xdr/cmd/genxdr/main.go index 5ebb7abaa..587ec7110 100644 --- a/Godeps/_workspace/src/github.com/calmh/xdr/cmd/genxdr/main.go +++ b/Godeps/_workspace/src/github.com/calmh/xdr/cmd/genxdr/main.go @@ -28,6 +28,7 @@ type fieldInfo struct { Encoder string // the encoder name, i.e. "Uint64" for Read/WriteUint64 Convert string // what to convert to when encoding, i.e. "uint64" Max int // max size for slices and strings + Submax int // max size for strings inside slices } type structInfo struct { @@ -156,7 +157,11 @@ func (o *{{.TypeName}}) DecodeXDRFrom(xr *xdr.Reader) error { {{if ne $fieldInfo.Convert ""}} o.{{$fieldInfo.Name}}[i] = {{$fieldInfo.FieldType}}(xr.Read{{$fieldInfo.Encoder}}()) {{else if $fieldInfo.IsBasic}} - o.{{$fieldInfo.Name}}[i] = xr.Read{{$fieldInfo.Encoder}}() + {{if ge $fieldInfo.Submax 1}} + o.{{$fieldInfo.Name}}[i] = xr.Read{{$fieldInfo.Encoder}}Max({{$fieldInfo.Submax}}) + {{else}} + o.{{$fieldInfo.Name}}[i] = xr.Read{{$fieldInfo.Encoder}}() + {{end}} {{else}} (&o.{{$fieldInfo.Name}}[i]).DecodeXDRFrom(xr) {{end}} @@ -166,7 +171,7 @@ func (o *{{.TypeName}}) DecodeXDRFrom(xr *xdr.Reader) error { return xr.Error() }`)) -var maxRe = regexp.MustCompile(`\Wmax:(\d+)`) +var maxRe = regexp.MustCompile(`(?:\Wmax:)(\d+)(?:\s*,\s*(\d+))?`) type typeSet struct { Type string @@ -198,11 +203,15 @@ func handleStruct(t *ast.StructType) []fieldInfo { } fn := sf.Names[0].Name - var max = 0 + var max1, max2 int if sf.Comment != nil { c := sf.Comment.List[0].Text - if m := maxRe.FindStringSubmatch(c); m != nil { - max, _ = strconv.Atoi(m[1]) + m := maxRe.FindStringSubmatch(c) + if len(m) >= 2 { + max1, _ = strconv.Atoi(m[1]) + } + if len(m) >= 3 { + max2, _ = strconv.Atoi(m[2]) } if strings.Contains(c, "noencode") { continue @@ -220,14 +229,16 @@ func handleStruct(t *ast.StructType) []fieldInfo { FieldType: tn, Encoder: enc.Encoder, Convert: enc.Type, - Max: max, + Max: max1, + Submax: max2, } } else { f = fieldInfo{ Name: fn, IsBasic: false, FieldType: tn, - Max: max, + Max: max1, + Submax: max2, } } @@ -245,7 +256,8 @@ func handleStruct(t *ast.StructType) []fieldInfo { FieldType: tn, Encoder: enc.Encoder, Convert: enc.Type, - Max: max, + Max: max1, + Submax: max2, } } else if enc, ok := xdrEncoders[tn]; ok { f = fieldInfo{ @@ -255,14 +267,16 @@ func handleStruct(t *ast.StructType) []fieldInfo { FieldType: tn, Encoder: enc.Encoder, Convert: enc.Type, - Max: max, + Max: max1, + Submax: max2, } } else { f = fieldInfo{ Name: fn, IsSlice: true, FieldType: tn, - Max: max, + Max: max1, + Submax: max2, } } @@ -270,7 +284,8 @@ func handleStruct(t *ast.StructType) []fieldInfo { f = fieldInfo{ Name: fn, FieldType: ft.Sel.Name, - Max: max, + Max: max1, + Submax: max2, } } From 491a33de0b09c69923bd55cce39309721000b389 Mon Sep 17 00:00:00 2001 From: Audrius Butkevicius Date: Sat, 26 Sep 2015 14:58:53 +0100 Subject: [PATCH 2/5] Move device name into the protocol messages --- lib/model/model.go | 23 ++++++++--------------- lib/protocol/message.go | 1 + lib/protocol/message_xdr.go | 12 ++++++++++++ 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/lib/model/model.go b/lib/model/model.go index a62ba2a3c..7385cc786 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -584,6 +584,7 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon event := map[string]string{ "id": deviceID.String(), + "deviceName": cm.DeviceName, "clientName": cm.ClientName, "clientVersion": cm.ClientVersion, } @@ -600,18 +601,15 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon events.Default.Log(events.DeviceConnected, event) - l.Infof(`Device %s client is "%s %s"`, deviceID, cm.ClientName, cm.ClientVersion) + l.Infof(`Device %s client is "%s %s named %s"`, deviceID, cm.ClientName, cm.ClientVersion, cm.DeviceName) var changed bool - if name := cm.GetOption("name"); name != "" { - l.Infof("Device %s name is %q", deviceID, name) - device, ok := m.cfg.Devices()[deviceID] - if ok && device.Name == "" { - device.Name = name - m.cfg.SetDevice(device) - changed = true - } + device, ok := m.cfg.Devices()[deviceID] + if ok && device.Name == "" { + device.Name = cm.DeviceName + m.cfg.SetDevice(device) + changed = true } if m.cfg.Devices()[deviceID].Introducer { @@ -1465,14 +1463,9 @@ func (m *Model) numHashers(folder string) int { // clusterConfig returns a ClusterConfigMessage that is correct for the given peer device func (m *Model) clusterConfig(device protocol.DeviceID) protocol.ClusterConfigMessage { cm := protocol.ClusterConfigMessage{ + DeviceName: m.deviceName, ClientName: m.clientName, ClientVersion: m.clientVersion, - Options: []protocol.Option{ - { - Key: "name", - Value: m.deviceName, - }, - }, } m.fmut.RLock() diff --git a/lib/protocol/message.go b/lib/protocol/message.go index d47cb3b3a..44870573e 100644 --- a/lib/protocol/message.go +++ b/lib/protocol/message.go @@ -110,6 +110,7 @@ type ResponseMessage struct { } type ClusterConfigMessage struct { + DeviceName string // max:64 ClientName string // max:64 ClientVersion string // max:64 Folders []Folder // max:1000000 diff --git a/lib/protocol/message_xdr.go b/lib/protocol/message_xdr.go index 81165f537..58d84ce4f 100644 --- a/lib/protocol/message_xdr.go +++ b/lib/protocol/message_xdr.go @@ -557,6 +557,12 @@ ClusterConfigMessage Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Length of Device Name | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +/ / +\ Device Name (variable length) \ +/ / ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Length of Client Name | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / @@ -584,6 +590,7 @@ ClusterConfigMessage Structure: struct ClusterConfigMessage { + string DeviceName<64>; string ClientName<64>; string ClientVersion<64>; Folder Folders<1000000>; @@ -617,6 +624,10 @@ func (o ClusterConfigMessage) AppendXDR(bs []byte) ([]byte, error) { } func (o ClusterConfigMessage) EncodeXDRInto(xw *xdr.Writer) (int, error) { + if l := len(o.DeviceName); l > 64 { + return xw.Tot(), xdr.ElementSizeExceeded("DeviceName", l, 64) + } + xw.WriteString(o.DeviceName) if l := len(o.ClientName); l > 64 { return xw.Tot(), xdr.ElementSizeExceeded("ClientName", l, 64) } @@ -660,6 +671,7 @@ func (o *ClusterConfigMessage) UnmarshalXDR(bs []byte) error { } func (o *ClusterConfigMessage) DecodeXDRFrom(xr *xdr.Reader) error { + o.DeviceName = xr.ReadStringMax(64) o.ClientName = xr.ReadStringMax(64) o.ClientVersion = xr.ReadStringMax(64) _FoldersSize := int(xr.ReadUint32()) From a323d85d32d94219b70a2cb13ebf8e9520684f14 Mon Sep 17 00:00:00 2001 From: Audrius Butkevicius Date: Sun, 27 Sep 2015 11:39:02 +0100 Subject: [PATCH 3/5] Add more information about the device to ClusterConfig --- lib/model/model.go | 26 +++++++++++++---- lib/protocol/message.go | 6 +++- lib/protocol/message_xdr.go | 56 +++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 6 deletions(-) diff --git a/lib/model/model.go b/lib/model/model.go index 7385cc786..43240aff5 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -632,11 +632,20 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon if _, ok := m.cfg.Devices()[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)", id, deviceID) newDeviceCfg := config.DeviceConfiguration{ DeviceID: id, + Name: device.Name, Compression: m.cfg.Devices()[deviceID].Compression, - Addresses: []string{"dynamic"}, + Addresses: addresses, + CertName: device.CertName, } // The introducers' introducers are also our introducers. @@ -1477,12 +1486,19 @@ func (m *Model) clusterConfig(device protocol.DeviceID) protocol.ClusterConfigMe // 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 - // TODO: Set read only bit when relevant + // TODO: Set read only bit when relevant, and when we have per device + // access controls. + deviceCfg := m.cfg.Devices()[device] cn := protocol.Device{ - ID: device[:], - Flags: protocol.FlagShareTrusted, + ID: device[:], + Name: deviceCfg.Name, + Addresses: deviceCfg.Addresses, + Compression: uint32(deviceCfg.Compression), + CertName: deviceCfg.CertName, + Flags: protocol.FlagShareTrusted, } - if deviceCfg := m.cfg.Devices()[device]; deviceCfg.Introducer { + + if deviceCfg.Introducer { cn.Flags |= protocol.FlagIntroducer } cr.Devices = append(cr.Devices, cn) diff --git a/lib/protocol/message.go b/lib/protocol/message.go index 44870573e..93353478e 100644 --- a/lib/protocol/message.go +++ b/lib/protocol/message.go @@ -134,7 +134,11 @@ type Folder struct { } type Device struct { - ID []byte // max:32 + ID []byte // max:32 + Name string // max:64 + Addresses []string // max:64,2083 + Compression uint32 + CertName string // max:64 MaxLocalVersion int64 Flags uint32 Options []Option // max:64 diff --git a/lib/protocol/message_xdr.go b/lib/protocol/message_xdr.go index 58d84ce4f..d2afb5383 100644 --- a/lib/protocol/message_xdr.go +++ b/lib/protocol/message_xdr.go @@ -842,6 +842,28 @@ Device Structure: \ ID (variable length) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Length of Name | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +/ / +\ Name (variable length) \ +/ / ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Number of Addresses | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Length of Addresses | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +/ / +\ Addresses (variable length) \ +/ / ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Compression | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Length of Cert Name | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +/ / +\ Cert Name (variable length) \ +/ / ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + Max Local Version (64 bits) + | | @@ -858,6 +880,10 @@ Device Structure: struct Device { opaque ID<32>; + string Name<64>; + string Addresses<64>; + unsigned int Compression; + string CertName<64>; hyper MaxLocalVersion; unsigned int Flags; Option Options<64>; @@ -894,6 +920,22 @@ func (o Device) EncodeXDRInto(xw *xdr.Writer) (int, error) { return xw.Tot(), xdr.ElementSizeExceeded("ID", l, 32) } xw.WriteBytes(o.ID) + if l := len(o.Name); l > 64 { + return xw.Tot(), xdr.ElementSizeExceeded("Name", l, 64) + } + xw.WriteString(o.Name) + if l := len(o.Addresses); l > 64 { + return xw.Tot(), xdr.ElementSizeExceeded("Addresses", l, 64) + } + xw.WriteUint32(uint32(len(o.Addresses))) + for i := range o.Addresses { + xw.WriteString(o.Addresses[i]) + } + xw.WriteUint32(o.Compression) + if l := len(o.CertName); l > 64 { + return xw.Tot(), xdr.ElementSizeExceeded("CertName", l, 64) + } + xw.WriteString(o.CertName) xw.WriteUint64(uint64(o.MaxLocalVersion)) xw.WriteUint32(o.Flags) if l := len(o.Options); l > 64 { @@ -922,6 +964,20 @@ func (o *Device) UnmarshalXDR(bs []byte) error { func (o *Device) DecodeXDRFrom(xr *xdr.Reader) error { o.ID = xr.ReadBytesMax(32) + o.Name = xr.ReadStringMax(64) + _AddressesSize := int(xr.ReadUint32()) + if _AddressesSize < 0 { + return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 64) + } + if _AddressesSize > 64 { + return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 64) + } + o.Addresses = make([]string, _AddressesSize) + for i := range o.Addresses { + o.Addresses[i] = xr.ReadStringMax(2083) + } + o.Compression = xr.ReadUint32() + o.CertName = xr.ReadStringMax(64) o.MaxLocalVersion = int64(xr.ReadUint64()) o.Flags = xr.ReadUint32() _OptionsSize := int(xr.ReadUint32()) From 9f4cd7716eed12d26331247d7279578254a4702d Mon Sep 17 00:00:00 2001 From: Audrius Butkevicius Date: Sun, 27 Sep 2015 12:11:34 +0100 Subject: [PATCH 4/5] Add more information about the folders to ClusterConfig --- lib/model/model.go | 12 ++++++++++++ lib/protocol/protocol.go | 7 +++++++ lib/relay/protocol/packets.go | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/model/model.go b/lib/model/model.go index 43240aff5..9161d8461 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -1479,9 +1479,21 @@ func (m *Model) clusterConfig(device protocol.DeviceID) protocol.ClusterConfigMe m.fmut.RLock() for _, folder := range m.deviceFolders[device] { + folderCfg := m.cfg.Folders()[folder] cr := protocol.Folder{ ID: folder, } + var flags uint32 + if folderCfg.ReadOnly { + flags |= protocol.FlagFolderReadOnly + } + if folderCfg.IgnorePerms { + flags |= protocol.FlagFolderIgnorePerms + } + if folderCfg.IgnoreDelete { + flags |= protocol.FlagFolderIgnoreDelete + } + cr.Flags = flags 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[:] diff --git a/lib/protocol/protocol.go b/lib/protocol/protocol.go index 0a1754a72..2420bf386 100644 --- a/lib/protocol/protocol.go +++ b/lib/protocol/protocol.go @@ -61,6 +61,13 @@ const ( FlagRequestTemporary uint32 = 1 << iota ) +// ClusterConfigMessage.Folders flags +const ( + FlagFolderReadOnly uint32 = 1 << 0 + FlagFolderIgnorePerms = 1 << 1 + FlagFolderIgnoreDelete = 1 << 2 +) + // ClusterConfigMessage.Folders.Devices flags const ( FlagShareTrusted uint32 = 1 << 0 diff --git a/lib/relay/protocol/packets.go b/lib/relay/protocol/packets.go index f11954caa..cd6ff620e 100644 --- a/lib/relay/protocol/packets.go +++ b/lib/relay/protocol/packets.go @@ -1,6 +1,6 @@ // Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file). -//go:generate -command genxdr go run ../../syncthing/Godeps/_workspace/src/github.com/calmh/xdr/cmd/genxdr/main.go +//go:generate -command genxdr go run ../../../Godeps/_workspace/src/github.com/calmh/xdr/cmd/genxdr/main.go //go:generate genxdr -o packets_xdr.go packets.go package protocol From afc917b5829a9d07af7b4b267096240a5722e0a9 Mon Sep 17 00:00:00 2001 From: Audrius Butkevicius Date: Sun, 27 Sep 2015 15:01:26 +0100 Subject: [PATCH 5/5] Fix tests --- lib/model/model_test.go | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/model/model_test.go b/lib/model/model_test.go index 6a831b76a..decfab16b 100644 --- a/lib/model/model_test.go +++ b/lib/model/model_test.go @@ -341,18 +341,13 @@ func TestDeviceRename(t *testing.T) { t.Errorf("Device already has a name") } - ccm.Options = []protocol.Option{ - { - Key: "name", - Value: "tester", - }, - } + ccm.DeviceName = "tester" m.ClusterConfig(device1, ccm) if cfg.Devices()[device1].Name != "tester" { t.Errorf("Device did not get a name") } - ccm.Options[0].Value = "tester2" + ccm.DeviceName = "tester2" m.ClusterConfig(device1, ccm) if cfg.Devices()[device1].Name != "tester" { t.Errorf("Device name got overwritten")