Ver Fonte

protocol: Add "Hello" message at connection start, also for unauthed peers

Audrius Butkevicius há 9 anos atrás
pai
commit
b4f9a55e6e

+ 3 - 3
gui/default/index.html

@@ -130,14 +130,14 @@
           </div>
           <div class="panel-body">
             <p>
-              <span translate translate-value-device="{{ device }}" translate-value-address="{{ event.data.address }}">
-                Device {%device%} ({%address%}) wants to connect. Add new device?
+              <span translate translate-value-device="{{ device }}" translate-value-address="{{ event.data.address }}" translate-value-name="{{ event.data.name }}">
+                Device "{%name%}" ({%device%} at {%address%}) wants to connect. Add new device?
               </span>
             </p>
           </div>
           <div class="panel-footer clearfix">
             <div class="pull-right">
-              <button type="button" class="btn btn-sm btn-success" ng-click="addDevice(device)">
+              <button type="button" class="btn btn-sm btn-success" ng-click="addDevice(device, event.data.name)">
                 <span class="fa fa-plus"></span>&nbsp;<span translate>Add Device</span>
               </button>
               <button type="button" class="btn btn-sm btn-danger" ng-click="ignoreRejectedDevice(device)">

+ 2 - 1
gui/default/syncthing/core/syncthingController.js

@@ -977,13 +977,14 @@ angular.module('syncthing.core')
             $('#idqr').modal('show');
         };
 
-        $scope.addDevice = function (deviceID) {
+        $scope.addDevice = function (deviceID, name) {
             return $http.get(urlbase + '/system/discovery')
                 .success(function (registry) {
                     $scope.discovery = registry;
                 })
                 .then(function () {
                     $scope.currentDevice = {
+                        name: name,
                         deviceID: deviceID,
                         _addressesStr: 'dynamic',
                         compression: 'metadata',

Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 1
lib/auto/gui.files.go


+ 77 - 25
lib/connections/connections.go

@@ -8,6 +8,7 @@ package connections
 
 import (
 	"crypto/tls"
+	"encoding/binary"
 	"fmt"
 	"io"
 	"net"
@@ -18,7 +19,6 @@ import (
 	"github.com/juju/ratelimit"
 	"github.com/syncthing/syncthing/lib/config"
 	"github.com/syncthing/syncthing/lib/discover"
-	"github.com/syncthing/syncthing/lib/events"
 	"github.com/syncthing/syncthing/lib/model"
 	"github.com/syncthing/syncthing/lib/protocol"
 	"github.com/syncthing/syncthing/lib/relay"
@@ -39,9 +39,11 @@ var (
 
 type Model interface {
 	protocol.Model
-	AddConnection(conn model.Connection)
+	AddConnection(conn model.Connection, hello protocol.HelloMessage)
 	ConnectedTo(remoteID protocol.DeviceID) bool
 	IsPaused(remoteID protocol.DeviceID) bool
+	OnHello(protocol.DeviceID, net.Addr, protocol.HelloMessage)
+	GetHello(protocol.DeviceID) protocol.HelloMessage
 }
 
 // Service listens on TLS and dials configured unconnected devices. Successful
@@ -144,14 +146,14 @@ func NewConnectionService(cfg *config.Wrapper, myID protocol.DeviceID, mdl Model
 func (s *Service) handle() {
 next:
 	for c := range s.conns {
-		cs := c.Conn.ConnectionState()
+		cs := c.ConnectionState()
 
 		// We should have negotiated the next level protocol "bep/1.0" as part
 		// of the TLS handshake. Unfortunately this can't be a hard error,
 		// because there are implementations out there that don't support
 		// protocol negotiation (iOS for one...).
 		if !cs.NegotiatedProtocolIsMutual || cs.NegotiatedProtocol != s.bepProtocolName {
-			l.Infof("Peer %s did not negotiate bep/1.0", c.Conn.RemoteAddr())
+			l.Infof("Peer %s did not negotiate bep/1.0", c.RemoteAddr())
 		}
 
 		// We should have received exactly one certificate from the other
@@ -159,8 +161,8 @@ next:
 		// connection.
 		certs := cs.PeerCertificates
 		if cl := len(certs); cl != 1 {
-			l.Infof("Got peer certificate list of length %d != 1 from %s; protocol error", cl, c.Conn.RemoteAddr())
-			c.Conn.Close()
+			l.Infof("Got peer certificate list of length %d != 1 from %s; protocol error", cl, c.RemoteAddr())
+			c.Close()
 			continue
 		}
 		remoteCert := certs[0]
@@ -171,10 +173,19 @@ next:
 		// clients between the same NAT gateway, and global discovery.
 		if remoteID == s.myID {
 			l.Infof("Connected to myself (%s) - should not happen", remoteID)
-			c.Conn.Close()
+			c.Close()
 			continue
 		}
 
+		hello, err := exchangeHello(c, s.model.GetHello(remoteID))
+		if err != nil {
+			l.Infof("Failed to exchange Hello messages with %s (%s): %s", remoteID, c.RemoteAddr(), err)
+			c.Close()
+			continue next
+		}
+
+		s.model.OnHello(remoteID, c.RemoteAddr(), hello)
+
 		// If we have a relay connection, and the new incoming connection is
 		// not a relay connection, we should drop that, and prefer the this one.
 		s.mut.RLock()
@@ -191,11 +202,11 @@ next:
 			// in parallel we don't want to do that or we end up with no
 			// connections still established...
 			l.Infof("Connected to already connected device (%s)", remoteID)
-			c.Conn.Close()
+			c.Close()
 			continue
 		} else if s.model.IsPaused(remoteID) {
 			l.Infof("Connection from paused device (%s)", remoteID)
-			c.Conn.Close()
+			c.Close()
 			continue
 		}
 
@@ -213,15 +224,15 @@ next:
 					// Incorrect certificate name is something the user most
 					// likely wants to know about, since it's an advanced
 					// config. Warn instead of Info.
-					l.Warnf("Bad certificate from %s (%v): %v", remoteID, c.Conn.RemoteAddr(), err)
-					c.Conn.Close()
+					l.Warnf("Bad certificate from %s (%v): %v", remoteID, c.RemoteAddr(), err)
+					c.Close()
 					continue next
 				}
 
 				// If rate limiting is set, and based on the address we should
 				// limit the connection, then we wrap it in a limiter.
 
-				limit := s.shouldLimit(c.Conn.RemoteAddr())
+				limit := s.shouldLimit(c.RemoteAddr())
 
 				wr := io.Writer(c.Conn)
 				if limit && s.writeRateLimit != nil {
@@ -233,17 +244,17 @@ next:
 					rd = NewReadLimiter(c.Conn, s.readRateLimit)
 				}
 
-				name := fmt.Sprintf("%s-%s (%s)", c.Conn.LocalAddr(), c.Conn.RemoteAddr(), c.Type)
+				name := fmt.Sprintf("%s-%s (%s)", c.LocalAddr(), c.RemoteAddr(), c.Type)
 				protoConn := protocol.NewConnection(remoteID, rd, wr, s.model, name, deviceCfg.Compression)
 
 				l.Infof("Established secure connection to %s at %s", remoteID, name)
-				l.Debugf("cipher suite: %04X in lan: %t", c.Conn.ConnectionState().CipherSuite, !limit)
+				l.Debugf("cipher suite: %04X in lan: %t", c.ConnectionState().CipherSuite, !limit)
 
 				s.model.AddConnection(model.Connection{
-					c.Conn,
+					c,
 					protoConn,
 					c.Type,
-				})
+				}, hello)
 				s.mut.Lock()
 				s.connType[remoteID] = c.Type
 				s.mut.Unlock()
@@ -251,15 +262,8 @@ next:
 			}
 		}
 
-		if !s.cfg.IgnoredDevice(remoteID) {
-			events.Default.Log(events.DeviceRejected, map[string]string{
-				"device":  remoteID.String(),
-				"address": c.Conn.RemoteAddr().String(),
-			})
-		}
-
-		l.Infof("Connection from %s (%s) with ignored device ID %s", c.Conn.RemoteAddr(), c.Type, remoteID)
-		c.Conn.Close()
+		l.Infof("Connection from %s (%s) with ignored device ID %s", c.RemoteAddr(), c.Type, remoteID)
+		c.Close()
 	}
 }
 
@@ -568,6 +572,54 @@ func isPublicIPv6(ip net.IP) bool {
 	return ip.IsGlobalUnicast()
 }
 
+func exchangeHello(c net.Conn, h protocol.HelloMessage) (protocol.HelloMessage, error) {
+	if err := c.SetDeadline(time.Now().Add(2 * time.Second)); err != nil {
+		return protocol.HelloMessage{}, err
+	}
+	defer c.SetDeadline(time.Time{})
+
+	header := make([]byte, 8)
+	msg := h.MustMarshalXDR()
+
+	binary.BigEndian.PutUint32(header[:4], protocol.HelloMessageMagic)
+	binary.BigEndian.PutUint32(header[4:], uint32(len(msg)))
+
+	if _, err := c.Write(header); err != nil {
+		return protocol.HelloMessage{}, err
+	}
+
+	if _, err := c.Write(msg); err != nil {
+		return protocol.HelloMessage{}, err
+	}
+
+	if _, err := io.ReadFull(c, header); err != nil {
+		return protocol.HelloMessage{}, err
+	}
+
+	if binary.BigEndian.Uint32(header[:4]) != protocol.HelloMessageMagic {
+		return protocol.HelloMessage{}, fmt.Errorf("incorrect magic")
+	}
+
+	msgSize := binary.BigEndian.Uint32(header[4:])
+	if msgSize > 1024 {
+		return protocol.HelloMessage{}, fmt.Errorf("hello message too big")
+	}
+
+	buf := make([]byte, msgSize)
+
+	var hello protocol.HelloMessage
+
+	if _, err := io.ReadFull(c, buf); err != nil {
+		return protocol.HelloMessage{}, err
+	}
+
+	if err := hello.UnmarshalXDR(buf); err != nil {
+		return protocol.HelloMessage{}, err
+	}
+
+	return hello, nil
+}
+
 // serviceFunc wraps a function to create a suture.Service without stop
 // functionality.
 type serviceFunc func()

+ 71 - 48
lib/model/model.go

@@ -87,10 +87,10 @@ type Model struct {
 	folderStatRefs     map[string]*stats.FolderStatisticsReference            // folder -> statsRef
 	fmut               sync.RWMutex                                           // protects the above
 
-	conn         map[protocol.DeviceID]Connection
-	deviceVer    map[protocol.DeviceID]string
-	devicePaused map[protocol.DeviceID]bool
-	pmut         sync.RWMutex // protects the above
+	conn          map[protocol.DeviceID]Connection
+	helloMessages map[protocol.DeviceID]protocol.HelloMessage
+	devicePaused  map[protocol.DeviceID]bool
+	pmut          sync.RWMutex // protects the above
 }
 
 var (
@@ -128,7 +128,7 @@ func NewModel(cfg *config.Wrapper, id protocol.DeviceID, deviceName, clientName,
 		folderRunnerTokens: make(map[string][]suture.ServiceToken),
 		folderStatRefs:     make(map[string]*stats.FolderStatisticsReference),
 		conn:               make(map[protocol.DeviceID]Connection),
-		deviceVer:          make(map[protocol.DeviceID]string),
+		helloMessages:      make(map[protocol.DeviceID]protocol.HelloMessage),
 		devicePaused:       make(map[protocol.DeviceID]bool),
 
 		fmut: sync.NewRWMutex(),
@@ -315,8 +315,13 @@ func (m *Model) ConnectionStats() map[string]interface{} {
 	devs := m.cfg.Devices()
 	conns := make(map[string]ConnectionInfo, len(devs))
 	for device := range devs {
+		hello := m.helloMessages[device]
+		versionString := hello.ClientVersion
+		if hello.ClientName != "syncthing" {
+			versionString = hello.ClientName + " " + hello.ClientVersion
+		}
 		ci := ConnectionInfo{
-			ClientVersion: m.deviceVer[device],
+			ClientVersion: versionString,
 			Paused:        m.devicePaused[device],
 		}
 		if conn, ok := m.conn[device]; ok {
@@ -606,30 +611,6 @@ func (m *Model) folderSharedWithUnlocked(folder string, deviceID protocol.Device
 }
 
 func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterConfigMessage) {
-	m.pmut.Lock()
-	if cm.ClientName == "syncthing" {
-		m.deviceVer[deviceID] = cm.ClientVersion
-	} else {
-		m.deviceVer[deviceID] = cm.ClientName + " " + cm.ClientVersion
-	}
-
-	event := map[string]string{
-		"id":            deviceID.String(),
-		"deviceName":    cm.DeviceName,
-		"clientName":    cm.ClientName,
-		"clientVersion": cm.ClientVersion,
-	}
-
-	if conn, ok := m.conn[deviceID]; ok {
-		event["type"] = conn.Type.String()
-		addr := conn.RemoteAddr()
-		if addr != nil {
-			event["addr"] = addr.String()
-		}
-	}
-
-	m.pmut.Unlock()
-
 	// Check the peer device's announced folders against our own. Emits events
 	// for folders that we don't expect (unknown or not shared).
 
@@ -661,19 +642,8 @@ nextFolder:
 	}
 	m.fmut.Unlock()
 
-	events.Default.Log(events.DeviceConnected, event)
-
-	l.Infof(`Device %s client is "%s %s" named "%s"`, deviceID, cm.ClientName, cm.ClientVersion, cm.DeviceName)
-
 	var changed bool
 
-	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 {
 		// This device is an introducer. Go through the announced lists of folders
 		// and devices and add what we are missing.
@@ -773,7 +743,7 @@ func (m *Model) Close(device protocol.DeviceID, err error) {
 		closeRawConn(conn)
 	}
 	delete(m.conn, device)
-	delete(m.deviceVer, device)
+	delete(m.helloMessages, device)
 	m.pmut.Unlock()
 }
 
@@ -978,10 +948,41 @@ func (m *Model) SetIgnores(folder string, content []string) error {
 	return m.ScanFolder(folder)
 }
 
+// OnHello is called when an device connects to us.
+// This allows us to extract some information from the Hello message
+// and add it to a list of known devices ahead of any checks.
+func (m *Model) OnHello(remoteID protocol.DeviceID, addr net.Addr, hello protocol.HelloMessage) {
+	for deviceID := range m.cfg.Devices() {
+		if deviceID == remoteID {
+			// Existing device, we will get the hello message in AddConnection
+			// hence do not persist any state here, as the connection might
+			// get killed before AddConnection
+			return
+		}
+	}
+
+	if !m.cfg.IgnoredDevice(remoteID) {
+		events.Default.Log(events.DeviceRejected, map[string]string{
+			"name":    hello.DeviceName,
+			"device":  remoteID.String(),
+			"address": addr.String(),
+		})
+	}
+}
+
+// GetHello is called when we are about to connect to some remote device.
+func (m *Model) GetHello(protocol.DeviceID) protocol.HelloMessage {
+	return protocol.HelloMessage{
+		DeviceName:    m.deviceName,
+		ClientName:    m.clientName,
+		ClientVersion: m.clientVersion,
+	}
+}
+
 // AddConnection adds a new peer connection to the model. An initial index will
 // be sent to the connected peer, thereafter index updates whenever the local
 // folder changes.
-func (m *Model) AddConnection(conn Connection) {
+func (m *Model) AddConnection(conn Connection, hello protocol.HelloMessage) {
 	deviceID := conn.ID()
 
 	m.pmut.Lock()
@@ -990,6 +991,32 @@ func (m *Model) AddConnection(conn Connection) {
 	}
 	m.conn[deviceID] = conn
 
+	m.helloMessages[deviceID] = hello
+
+	event := map[string]string{
+		"id":            deviceID.String(),
+		"deviceName":    hello.DeviceName,
+		"clientName":    hello.ClientName,
+		"clientVersion": hello.ClientVersion,
+		"type":          conn.Type.String(),
+	}
+
+	addr := conn.RemoteAddr()
+	if addr != nil {
+		event["addr"] = addr.String()
+	}
+
+	events.Default.Log(events.DeviceConnected, event)
+
+	l.Infof(`Device %s client is "%s %s" named "%s"`, deviceID, hello.ClientName, hello.ClientVersion, hello.DeviceName)
+
+	device, ok := m.cfg.Devices()[deviceID]
+	if ok && device.Name == "" {
+		device.Name = hello.DeviceName
+		m.cfg.SetDevice(device)
+		m.cfg.Save()
+	}
+
 	conn.Start()
 
 	cm := m.generateClusterConfig(deviceID)
@@ -1510,11 +1537,7 @@ func (m *Model) numHashers(folder string) int {
 // generateClusterConfig returns a ClusterConfigMessage that is correct for
 // the given peer device
 func (m *Model) generateClusterConfig(device protocol.DeviceID) protocol.ClusterConfigMessage {
-	message := protocol.ClusterConfigMessage{
-		DeviceName:    m.deviceName,
-		ClientName:    m.clientName,
-		ClientVersion: m.clientVersion,
-	}
+	var message protocol.ClusterConfigMessage
 
 	m.fmut.RLock()
 	for _, folder := range m.deviceFolders[device] {

+ 20 - 17
lib/model/model_test.go

@@ -279,7 +279,7 @@ func BenchmarkRequest(b *testing.B) {
 		&net.TCPConn{},
 		fc,
 		ConnectionTypeDirectAccept,
-	})
+	}, protocol.HelloMessage{})
 	m.Index(device1, "default", files, 0, nil)
 
 	b.ResetTimer()
@@ -295,11 +295,10 @@ func BenchmarkRequest(b *testing.B) {
 }
 
 func TestDeviceRename(t *testing.T) {
-	ccm := protocol.ClusterConfigMessage{
+	hello := protocol.HelloMessage{
 		ClientName:    "syncthing",
 		ClientVersion: "v0.9.4",
 	}
-
 	defer os.Remove("tmpconfig.xml")
 
 	rawCfg := config.New(device1)
@@ -313,35 +312,39 @@ func TestDeviceRename(t *testing.T) {
 	db := db.OpenMemory()
 	m := NewModel(cfg, protocol.LocalDeviceID, "device", "syncthing", "dev", db, nil)
 
-	fc := FakeConnection{
-		id:          device1,
-		requestData: []byte("some data to return"),
+	if cfg.Devices()[device1].Name != "" {
+		t.Errorf("Device already has a name")
 	}
 
-	m.AddConnection(Connection{
+	conn := Connection{
 		&net.TCPConn{},
-		fc,
+		FakeConnection{
+			id:          device1,
+			requestData: []byte("some data to return"),
+		},
 		ConnectionTypeDirectAccept,
-	})
+	}
+
+	m.AddConnection(conn, hello)
 
 	m.ServeBackground()
-	if cfg.Devices()[device1].Name != "" {
-		t.Errorf("Device already has a name")
-	}
 
-	m.ClusterConfig(device1, ccm)
 	if cfg.Devices()[device1].Name != "" {
 		t.Errorf("Device already has a name")
 	}
 
-	ccm.DeviceName = "tester"
-	m.ClusterConfig(device1, ccm)
+	m.Close(device1, protocol.ErrTimeout)
+	hello.DeviceName = "tester"
+	m.AddConnection(conn, hello)
+
 	if cfg.Devices()[device1].Name != "tester" {
 		t.Errorf("Device did not get a name")
 	}
 
-	ccm.DeviceName = "tester2"
-	m.ClusterConfig(device1, ccm)
+	m.Close(device1, protocol.ErrTimeout)
+	hello.DeviceName = "tester2"
+	m.AddConnection(conn, hello)
+
 	if cfg.Devices()[device1].Name != "tester" {
 		t.Errorf("Device name got overwritten")
 	}

+ 12 - 6
lib/protocol/message.go

@@ -11,7 +11,16 @@ import (
 	"fmt"
 )
 
-var sha256OfEmptyBlock = sha256.Sum256(make([]byte, BlockSize))
+var (
+	sha256OfEmptyBlock        = sha256.Sum256(make([]byte, BlockSize))
+	HelloMessageMagic  uint32 = 0x9F79BC40
+)
+
+type HelloMessage struct {
+	DeviceName    string // max:64
+	ClientName    string // max:64
+	ClientVersion string // max:64
+}
 
 type IndexMessage struct {
 	Folder  string     // max:256
@@ -125,11 +134,8 @@ type ResponseMessage struct {
 }
 
 type ClusterConfigMessage struct {
-	DeviceName    string   // max:64
-	ClientName    string   // max:64
-	ClientVersion string   // max:64
-	Folders       []Folder // max:1000000
-	Options       []Option // max:64
+	Folders []Folder // max:1000000
+	Options []Option // max:64
 }
 
 func (o *ClusterConfigMessage) GetOption(key string) string {

+ 77 - 34
lib/protocol/message_xdr.go

@@ -10,6 +10,82 @@ import (
 
 /*
 
+HelloMessage 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
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+/                                                               /
+\              Device Name (length + padded data)               \
+/                                                               /
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+/                                                               /
+\              Client Name (length + padded data)               \
+/                                                               /
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+/                                                               /
+\             Client Version (length + padded data)             \
+/                                                               /
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+struct HelloMessage {
+	string DeviceName<64>;
+	string ClientName<64>;
+	string ClientVersion<64>;
+}
+
+*/
+
+func (o HelloMessage) XDRSize() int {
+	return 4 + len(o.DeviceName) + xdr.Padding(len(o.DeviceName)) +
+		4 + len(o.ClientName) + xdr.Padding(len(o.ClientName)) +
+		4 + len(o.ClientVersion) + xdr.Padding(len(o.ClientVersion))
+}
+
+func (o HelloMessage) MarshalXDR() ([]byte, error) {
+	buf := make([]byte, o.XDRSize())
+	m := &xdr.Marshaller{Data: buf}
+	return buf, o.MarshalXDRInto(m)
+}
+
+func (o HelloMessage) MustMarshalXDR() []byte {
+	bs, err := o.MarshalXDR()
+	if err != nil {
+		panic(err)
+	}
+	return bs
+}
+
+func (o HelloMessage) MarshalXDRInto(m *xdr.Marshaller) error {
+	if l := len(o.DeviceName); l > 64 {
+		return xdr.ElementSizeExceeded("DeviceName", l, 64)
+	}
+	m.MarshalString(o.DeviceName)
+	if l := len(o.ClientName); l > 64 {
+		return xdr.ElementSizeExceeded("ClientName", l, 64)
+	}
+	m.MarshalString(o.ClientName)
+	if l := len(o.ClientVersion); l > 64 {
+		return xdr.ElementSizeExceeded("ClientVersion", l, 64)
+	}
+	m.MarshalString(o.ClientVersion)
+	return m.Error
+}
+
+func (o *HelloMessage) UnmarshalXDR(bs []byte) error {
+	u := &xdr.Unmarshaller{Data: bs}
+	return o.UnmarshalXDRFrom(u)
+}
+func (o *HelloMessage) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
+	o.DeviceName = u.UnmarshalStringMax(64)
+	o.ClientName = u.UnmarshalStringMax(64)
+	o.ClientVersion = u.UnmarshalStringMax(64)
+	return u.Error
+}
+
+/*
+
 IndexMessage Structure:
 
  0                   1                   2                   3
@@ -506,18 +582,6 @@ 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
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-/                                                               /
-\              Device Name (length + padded data)               \
-/                                                               /
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-/                                                               /
-\              Client Name (length + padded data)               \
-/                                                               /
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-/                                                               /
-\             Client Version (length + padded data)             \
-/                                                               /
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                       Number of Folders                       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 /                                                               /
@@ -533,9 +597,6 @@ ClusterConfigMessage Structure:
 
 
 struct ClusterConfigMessage {
-	string DeviceName<64>;
-	string ClientName<64>;
-	string ClientVersion<64>;
 	Folder Folders<1000000>;
 	Option Options<64>;
 }
@@ -543,10 +604,7 @@ struct ClusterConfigMessage {
 */
 
 func (o ClusterConfigMessage) XDRSize() int {
-	return 4 + len(o.DeviceName) + xdr.Padding(len(o.DeviceName)) +
-		4 + len(o.ClientName) + xdr.Padding(len(o.ClientName)) +
-		4 + len(o.ClientVersion) + xdr.Padding(len(o.ClientVersion)) +
-		4 + xdr.SizeOfSlice(o.Folders) +
+	return 4 + xdr.SizeOfSlice(o.Folders) +
 		4 + xdr.SizeOfSlice(o.Options)
 }
 
@@ -565,18 +623,6 @@ func (o ClusterConfigMessage) MustMarshalXDR() []byte {
 }
 
 func (o ClusterConfigMessage) MarshalXDRInto(m *xdr.Marshaller) error {
-	if l := len(o.DeviceName); l > 64 {
-		return xdr.ElementSizeExceeded("DeviceName", l, 64)
-	}
-	m.MarshalString(o.DeviceName)
-	if l := len(o.ClientName); l > 64 {
-		return xdr.ElementSizeExceeded("ClientName", l, 64)
-	}
-	m.MarshalString(o.ClientName)
-	if l := len(o.ClientVersion); l > 64 {
-		return xdr.ElementSizeExceeded("ClientVersion", l, 64)
-	}
-	m.MarshalString(o.ClientVersion)
 	if l := len(o.Folders); l > 1000000 {
 		return xdr.ElementSizeExceeded("Folders", l, 1000000)
 	}
@@ -603,9 +649,6 @@ func (o *ClusterConfigMessage) UnmarshalXDR(bs []byte) error {
 	return o.UnmarshalXDRFrom(u)
 }
 func (o *ClusterConfigMessage) UnmarshalXDRFrom(u *xdr.Unmarshaller) error {
-	o.DeviceName = u.UnmarshalStringMax(64)
-	o.ClientName = u.UnmarshalStringMax(64)
-	o.ClientVersion = u.UnmarshalStringMax(64)
 	_FoldersSize := int(u.UnmarshalUint32())
 	if _FoldersSize < 0 {
 		return xdr.ElementSizeExceeded("Folders", _FoldersSize, 1000000)

+ 2 - 2
lib/protocol/protocol_test.go

@@ -189,12 +189,12 @@ func TestClose(t *testing.T) {
 }
 
 func TestElementSizeExceededNested(t *testing.T) {
-	m := ClusterConfigMessage{
+	m := HelloMessage{
 		ClientName: "longstringlongstringlongstringinglongstringlongstringlonlongstringlongstringlon",
 	}
 	_, err := m.MarshalXDR()
 	if err == nil {
-		t.Errorf("ID length %d > max 64, but no error", len(m.Folders[0].ID))
+		t.Errorf("ID length %d > max 64, but no error", len(m.ClientName))
 	}
 }
 

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff