summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Borg <jakob@kastelo.net>2016-12-17 12:05:09 +0100
committerJakob Borg <jakob@kastelo.net>2016-12-17 12:39:22 +0100
commit0437f6dd663b3d8c6f1732d65825066c4d7ef37b (patch)
tree7f0cab39485a5c51cb4de732b09f6206577075bd
parent11b35d650d279000b2207549100001e089e637c6 (diff)
downloadsyncthing-0.14.15.tar.gz
syncthing-0.14.15.zip
lib/model: Don't send symlinks to old devices that can't handle them (fixes #3802)v0.14.15
-rw-r--r--lib/model/model.go28
1 files changed, 23 insertions, 5 deletions
diff --git a/lib/model/model.go b/lib/model/model.go
index 2d536824f..dfc08c7cf 100644
--- a/lib/model/model.go
+++ b/lib/model/model.go
@@ -35,6 +35,7 @@ import (
"github.com/syncthing/syncthing/lib/stats"
"github.com/syncthing/syncthing/lib/symlinks"
"github.com/syncthing/syncthing/lib/sync"
+ "github.com/syncthing/syncthing/lib/upgrade"
"github.com/syncthing/syncthing/lib/versioner"
"github.com/thejerf/suture"
)
@@ -764,6 +765,7 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
m.pmut.RLock()
conn, ok := m.conn[deviceID]
+ hello := m.helloMessages[deviceID]
m.pmut.RUnlock()
if !ok {
panic("bug: ClusterConfig called on closed or nonexistent connection")
@@ -771,6 +773,14 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
dbLocation := filepath.Dir(m.db.Location())
+ // See issue #3802 - in short, we can't send modern symlink entries to older
+ // clients.
+ dropSymlinks := false
+ if hello.ClientName == m.clientName && upgrade.CompareVersions(hello.ClientVersion, "v0.14.14") < 0 {
+ l.Warnln("Not sending symlinks to old client", deviceID, "- please upgrade to v0.14.14 or newer")
+ dropSymlinks = true
+ }
+
m.fmut.Lock()
for _, folder := range cm.Folders {
if !m.folderSharedWithLocked(folder.ID, deviceID) {
@@ -857,7 +867,7 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
}
}
- go sendIndexes(conn, folder.ID, fs, m.folderIgnores[folder.ID], startSequence, dbLocation)
+ go sendIndexes(conn, folder.ID, fs, m.folderIgnores[folder.ID], startSequence, dbLocation, dropSymlinks)
}
// This breaks if we send multiple CM messages during the same connection.
@@ -1434,7 +1444,7 @@ func (m *Model) receivedFile(folder string, file protocol.FileInfo) {
m.folderStatRef(folder).ReceivedFile(file.Name, file.IsDeleted())
}
-func sendIndexes(conn protocol.Connection, folder string, fs *db.FileSet, ignores *ignore.Matcher, startSequence int64, dbLocation string) {
+func sendIndexes(conn protocol.Connection, folder string, fs *db.FileSet, ignores *ignore.Matcher, startSequence int64, dbLocation string, dropSymlinks bool) {
deviceID := conn.ID()
name := conn.Name()
var err error
@@ -1442,7 +1452,7 @@ func sendIndexes(conn protocol.Connection, folder string, fs *db.FileSet, ignore
l.Debugf("sendIndexes for %s-%s/%q starting (slv=%d)", deviceID, name, folder, startSequence)
defer l.Debugf("sendIndexes for %s-%s/%q exiting: %v", deviceID, name, folder, err)
- minSequence, err := sendIndexTo(startSequence, conn, folder, fs, ignores, dbLocation)
+ minSequence, err := sendIndexTo(startSequence, conn, folder, fs, ignores, dbLocation, dropSymlinks)
// Subscribe to LocalIndexUpdated (we have new information to send) and
// DeviceDisconnected (it might be us who disconnected, so we should
@@ -1465,7 +1475,7 @@ func sendIndexes(conn protocol.Connection, folder string, fs *db.FileSet, ignore
continue
}
- minSequence, err = sendIndexTo(minSequence, conn, folder, fs, ignores, dbLocation)
+ minSequence, err = sendIndexTo(minSequence, conn, folder, fs, ignores, dbLocation, dropSymlinks)
// Wait a short amount of time before entering the next loop. If there
// are continuous changes happening to the local index, this gives us
@@ -1474,7 +1484,7 @@ func sendIndexes(conn protocol.Connection, folder string, fs *db.FileSet, ignore
}
}
-func sendIndexTo(minSequence int64, conn protocol.Connection, folder string, fs *db.FileSet, ignores *ignore.Matcher, dbLocation string) (int64, error) {
+func sendIndexTo(minSequence int64, conn protocol.Connection, folder string, fs *db.FileSet, ignores *ignore.Matcher, dbLocation string, dropSymlinks bool) (int64, error) {
deviceID := conn.ID()
name := conn.Name()
batch := make([]protocol.FileInfo, 0, indexBatchSize)
@@ -1496,6 +1506,14 @@ func sendIndexTo(minSequence int64, conn protocol.Connection, folder string, fs
maxSequence = f.Sequence
}
+ if dropSymlinks && f.IsSymlink() {
+ // Do not send index entries with symlinks to clients that can't
+ // handle it. Fixes issue #3802. Once both sides are upgraded, a
+ // rescan (i.e., change) of the symlink is required for it to
+ // sync again, due to delta indexes.
+ return true
+ }
+
sorter.Append(f)
return true
})