Merge pull request #2320 from AudriusButkevicius/proto

More proto changes
This commit is contained in:
Jakob Borg 2015-10-18 08:47:30 +02:00
commit 6578ffe2c9
10 changed files with 154 additions and 43 deletions

2
Godeps/Godeps.json generated
View File

@ -19,7 +19,7 @@
}, },
{ {
"ImportPath": "github.com/calmh/xdr", "ImportPath": "github.com/calmh/xdr",
"Rev": "5f7208e86762911861c94f1849eddbfc0a60cbf0" "Rev": "47c0042d09a827b81ee62497f99e5e0c7f0bd31c"
}, },
{ {
"ImportPath": "github.com/golang/snappy", "ImportPath": "github.com/golang/snappy",

View File

@ -4,7 +4,7 @@ go:
install: install:
- export PATH=$PATH:$HOME/gopath/bin - 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 - go get github.com/mattn/goveralls
script: script:

View File

@ -1,7 +1,7 @@
xdr 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) [![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) [![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) [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](http://opensource.org/licenses/MIT)

View File

@ -28,6 +28,7 @@ type fieldInfo struct {
Encoder string // the encoder name, i.e. "Uint64" for Read/WriteUint64 Encoder string // the encoder name, i.e. "Uint64" for Read/WriteUint64
Convert string // what to convert to when encoding, i.e. "uint64" Convert string // what to convert to when encoding, i.e. "uint64"
Max int // max size for slices and strings Max int // max size for slices and strings
Submax int // max size for strings inside slices
} }
type structInfo struct { type structInfo struct {
@ -156,7 +157,11 @@ func (o *{{.TypeName}}) DecodeXDRFrom(xr *xdr.Reader) error {
{{if ne $fieldInfo.Convert ""}} {{if ne $fieldInfo.Convert ""}}
o.{{$fieldInfo.Name}}[i] = {{$fieldInfo.FieldType}}(xr.Read{{$fieldInfo.Encoder}}()) o.{{$fieldInfo.Name}}[i] = {{$fieldInfo.FieldType}}(xr.Read{{$fieldInfo.Encoder}}())
{{else if $fieldInfo.IsBasic}} {{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}} {{else}}
(&o.{{$fieldInfo.Name}}[i]).DecodeXDRFrom(xr) (&o.{{$fieldInfo.Name}}[i]).DecodeXDRFrom(xr)
{{end}} {{end}}
@ -166,7 +171,7 @@ func (o *{{.TypeName}}) DecodeXDRFrom(xr *xdr.Reader) error {
return xr.Error() return xr.Error()
}`)) }`))
var maxRe = regexp.MustCompile(`\Wmax:(\d+)`) var maxRe = regexp.MustCompile(`(?:\Wmax:)(\d+)(?:\s*,\s*(\d+))?`)
type typeSet struct { type typeSet struct {
Type string Type string
@ -198,11 +203,15 @@ func handleStruct(t *ast.StructType) []fieldInfo {
} }
fn := sf.Names[0].Name fn := sf.Names[0].Name
var max = 0 var max1, max2 int
if sf.Comment != nil { if sf.Comment != nil {
c := sf.Comment.List[0].Text c := sf.Comment.List[0].Text
if m := maxRe.FindStringSubmatch(c); m != nil { m := maxRe.FindStringSubmatch(c)
max, _ = strconv.Atoi(m[1]) if len(m) >= 2 {
max1, _ = strconv.Atoi(m[1])
}
if len(m) >= 3 {
max2, _ = strconv.Atoi(m[2])
} }
if strings.Contains(c, "noencode") { if strings.Contains(c, "noencode") {
continue continue
@ -220,14 +229,16 @@ func handleStruct(t *ast.StructType) []fieldInfo {
FieldType: tn, FieldType: tn,
Encoder: enc.Encoder, Encoder: enc.Encoder,
Convert: enc.Type, Convert: enc.Type,
Max: max, Max: max1,
Submax: max2,
} }
} else { } else {
f = fieldInfo{ f = fieldInfo{
Name: fn, Name: fn,
IsBasic: false, IsBasic: false,
FieldType: tn, FieldType: tn,
Max: max, Max: max1,
Submax: max2,
} }
} }
@ -245,7 +256,8 @@ func handleStruct(t *ast.StructType) []fieldInfo {
FieldType: tn, FieldType: tn,
Encoder: enc.Encoder, Encoder: enc.Encoder,
Convert: enc.Type, Convert: enc.Type,
Max: max, Max: max1,
Submax: max2,
} }
} else if enc, ok := xdrEncoders[tn]; ok { } else if enc, ok := xdrEncoders[tn]; ok {
f = fieldInfo{ f = fieldInfo{
@ -255,14 +267,16 @@ func handleStruct(t *ast.StructType) []fieldInfo {
FieldType: tn, FieldType: tn,
Encoder: enc.Encoder, Encoder: enc.Encoder,
Convert: enc.Type, Convert: enc.Type,
Max: max, Max: max1,
Submax: max2,
} }
} else { } else {
f = fieldInfo{ f = fieldInfo{
Name: fn, Name: fn,
IsSlice: true, IsSlice: true,
FieldType: tn, FieldType: tn,
Max: max, Max: max1,
Submax: max2,
} }
} }
@ -270,7 +284,8 @@ func handleStruct(t *ast.StructType) []fieldInfo {
f = fieldInfo{ f = fieldInfo{
Name: fn, Name: fn,
FieldType: ft.Sel.Name, FieldType: ft.Sel.Name,
Max: max, Max: max1,
Submax: max2,
} }
} }

View File

@ -584,6 +584,7 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
event := map[string]string{ event := map[string]string{
"id": deviceID.String(), "id": deviceID.String(),
"deviceName": cm.DeviceName,
"clientName": cm.ClientName, "clientName": cm.ClientName,
"clientVersion": cm.ClientVersion, "clientVersion": cm.ClientVersion,
} }
@ -600,18 +601,15 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
events.Default.Log(events.DeviceConnected, event) 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 var changed bool
if name := cm.GetOption("name"); name != "" { device, ok := m.cfg.Devices()[deviceID]
l.Infof("Device %s name is %q", deviceID, name) if ok && device.Name == "" {
device, ok := m.cfg.Devices()[deviceID] device.Name = cm.DeviceName
if ok && device.Name == "" { m.cfg.SetDevice(device)
device.Name = name changed = true
m.cfg.SetDevice(device)
changed = true
}
} }
if m.cfg.Devices()[deviceID].Introducer { if m.cfg.Devices()[deviceID].Introducer {
@ -634,11 +632,20 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
if _, ok := m.cfg.Devices()[id]; !ok { if _, ok := m.cfg.Devices()[id]; !ok {
// The device is currently unknown. Add it to the config. // 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) l.Infof("Adding device %v to config (vouched for by introducer %v)", id, deviceID)
newDeviceCfg := config.DeviceConfiguration{ newDeviceCfg := config.DeviceConfiguration{
DeviceID: id, DeviceID: id,
Name: device.Name,
Compression: m.cfg.Devices()[deviceID].Compression, Compression: m.cfg.Devices()[deviceID].Compression,
Addresses: []string{"dynamic"}, Addresses: addresses,
CertName: device.CertName,
} }
// The introducers' introducers are also our introducers. // The introducers' introducers are also our introducers.
@ -1465,31 +1472,45 @@ func (m *Model) numHashers(folder string) int {
// clusterConfig returns a ClusterConfigMessage that is correct for the given peer device // clusterConfig returns a ClusterConfigMessage that is correct for the given peer device
func (m *Model) clusterConfig(device protocol.DeviceID) protocol.ClusterConfigMessage { func (m *Model) clusterConfig(device protocol.DeviceID) protocol.ClusterConfigMessage {
cm := protocol.ClusterConfigMessage{ cm := protocol.ClusterConfigMessage{
DeviceName: m.deviceName,
ClientName: m.clientName, ClientName: m.clientName,
ClientVersion: m.clientVersion, ClientVersion: m.clientVersion,
Options: []protocol.Option{
{
Key: "name",
Value: m.deviceName,
},
},
} }
m.fmut.RLock() m.fmut.RLock()
for _, folder := range m.deviceFolders[device] { for _, folder := range m.deviceFolders[device] {
folderCfg := m.cfg.Folders()[folder]
cr := protocol.Folder{ cr := protocol.Folder{
ID: 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] { for _, device := range m.folderDevices[folder] {
// DeviceID is a value type, but with an underlying array. Copy it // 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[:] // so we don't grab aliases to the same array later on in device[:]
device := 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{ cn := protocol.Device{
ID: device[:], ID: device[:],
Flags: protocol.FlagShareTrusted, 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 cn.Flags |= protocol.FlagIntroducer
} }
cr.Devices = append(cr.Devices, cn) cr.Devices = append(cr.Devices, cn)

View File

@ -341,18 +341,13 @@ func TestDeviceRename(t *testing.T) {
t.Errorf("Device already has a name") t.Errorf("Device already has a name")
} }
ccm.Options = []protocol.Option{ ccm.DeviceName = "tester"
{
Key: "name",
Value: "tester",
},
}
m.ClusterConfig(device1, ccm) m.ClusterConfig(device1, ccm)
if cfg.Devices()[device1].Name != "tester" { if cfg.Devices()[device1].Name != "tester" {
t.Errorf("Device did not get a name") t.Errorf("Device did not get a name")
} }
ccm.Options[0].Value = "tester2" ccm.DeviceName = "tester2"
m.ClusterConfig(device1, ccm) m.ClusterConfig(device1, ccm)
if cfg.Devices()[device1].Name != "tester" { if cfg.Devices()[device1].Name != "tester" {
t.Errorf("Device name got overwritten") t.Errorf("Device name got overwritten")

View File

@ -110,6 +110,7 @@ type ResponseMessage struct {
} }
type ClusterConfigMessage struct { type ClusterConfigMessage struct {
DeviceName string // max:64
ClientName string // max:64 ClientName string // max:64
ClientVersion string // max:64 ClientVersion string // max:64
Folders []Folder // max:1000000 Folders []Folder // max:1000000
@ -133,7 +134,11 @@ type Folder struct {
} }
type Device 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 MaxLocalVersion int64
Flags uint32 Flags uint32
Options []Option // max:64 Options []Option // max:64

View File

@ -557,6 +557,12 @@ ClusterConfigMessage Structure:
0 1 2 3 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 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 | | Length of Client Name |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ / / /
@ -584,6 +590,7 @@ ClusterConfigMessage Structure:
struct ClusterConfigMessage { struct ClusterConfigMessage {
string DeviceName<64>;
string ClientName<64>; string ClientName<64>;
string ClientVersion<64>; string ClientVersion<64>;
Folder Folders<1000000>; Folder Folders<1000000>;
@ -617,6 +624,10 @@ func (o ClusterConfigMessage) AppendXDR(bs []byte) ([]byte, error) {
} }
func (o ClusterConfigMessage) EncodeXDRInto(xw *xdr.Writer) (int, 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 { if l := len(o.ClientName); l > 64 {
return xw.Tot(), xdr.ElementSizeExceeded("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 { func (o *ClusterConfigMessage) DecodeXDRFrom(xr *xdr.Reader) error {
o.DeviceName = xr.ReadStringMax(64)
o.ClientName = xr.ReadStringMax(64) o.ClientName = xr.ReadStringMax(64)
o.ClientVersion = xr.ReadStringMax(64) o.ClientVersion = xr.ReadStringMax(64)
_FoldersSize := int(xr.ReadUint32()) _FoldersSize := int(xr.ReadUint32())
@ -830,6 +842,28 @@ Device Structure:
\ ID (variable length) \ \ 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) + + Max Local Version (64 bits) +
| | | |
@ -846,6 +880,10 @@ Device Structure:
struct Device { struct Device {
opaque ID<32>; opaque ID<32>;
string Name<64>;
string Addresses<64>;
unsigned int Compression;
string CertName<64>;
hyper MaxLocalVersion; hyper MaxLocalVersion;
unsigned int Flags; unsigned int Flags;
Option Options<64>; Option Options<64>;
@ -882,6 +920,22 @@ func (o Device) EncodeXDRInto(xw *xdr.Writer) (int, error) {
return xw.Tot(), xdr.ElementSizeExceeded("ID", l, 32) return xw.Tot(), xdr.ElementSizeExceeded("ID", l, 32)
} }
xw.WriteBytes(o.ID) 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.WriteUint64(uint64(o.MaxLocalVersion))
xw.WriteUint32(o.Flags) xw.WriteUint32(o.Flags)
if l := len(o.Options); l > 64 { if l := len(o.Options); l > 64 {
@ -910,6 +964,20 @@ func (o *Device) UnmarshalXDR(bs []byte) error {
func (o *Device) DecodeXDRFrom(xr *xdr.Reader) error { func (o *Device) DecodeXDRFrom(xr *xdr.Reader) error {
o.ID = xr.ReadBytesMax(32) 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.MaxLocalVersion = int64(xr.ReadUint64())
o.Flags = xr.ReadUint32() o.Flags = xr.ReadUint32()
_OptionsSize := int(xr.ReadUint32()) _OptionsSize := int(xr.ReadUint32())

View File

@ -61,6 +61,13 @@ const (
FlagRequestTemporary uint32 = 1 << iota FlagRequestTemporary uint32 = 1 << iota
) )
// ClusterConfigMessage.Folders flags
const (
FlagFolderReadOnly uint32 = 1 << 0
FlagFolderIgnorePerms = 1 << 1
FlagFolderIgnoreDelete = 1 << 2
)
// ClusterConfigMessage.Folders.Devices flags // ClusterConfigMessage.Folders.Devices flags
const ( const (
FlagShareTrusted uint32 = 1 << 0 FlagShareTrusted uint32 = 1 << 0

View File

@ -1,6 +1,6 @@
// Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file). // 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 //go:generate genxdr -o packets_xdr.go packets.go
package protocol package protocol