Add version and invalid bit to protocol
This commit is contained in:
@@ -56,8 +56,6 @@ type Model struct {
|
||||
}
|
||||
|
||||
const (
|
||||
FlagDeleted = 1 << 12
|
||||
|
||||
idxBcastHoldtime = 15 * time.Second // Wait at least this long after the last index modification
|
||||
idxBcastMaxDelay = 120 * time.Second // Unless we've already waited this long
|
||||
|
||||
@@ -65,7 +63,10 @@ const (
|
||||
maxFileHoldTimeS = 600 // Always allow file changes at least this often
|
||||
)
|
||||
|
||||
var ErrNoSuchFile = errors.New("no such file")
|
||||
var (
|
||||
ErrNoSuchFile = errors.New("no such file")
|
||||
ErrInvalid = errors.New("file is invalid")
|
||||
)
|
||||
|
||||
// NewModel creates and starts a new model. The model starts in read-only mode,
|
||||
// where it sends index information to connected peers and responds to requests
|
||||
@@ -159,7 +160,7 @@ func (m *Model) GlobalSize() (files, deleted, bytes int) {
|
||||
defer m.RUnlock()
|
||||
|
||||
for _, f := range m.global {
|
||||
if f.Flags&FlagDeleted == 0 {
|
||||
if f.Flags&protocol.FlagDeleted == 0 {
|
||||
files++
|
||||
bytes += f.Size()
|
||||
} else {
|
||||
@@ -176,7 +177,7 @@ func (m *Model) LocalSize() (files, deleted, bytes int) {
|
||||
defer m.RUnlock()
|
||||
|
||||
for _, f := range m.local {
|
||||
if f.Flags&FlagDeleted == 0 {
|
||||
if f.Flags&protocol.FlagDeleted == 0 {
|
||||
files++
|
||||
bytes += f.Size()
|
||||
} else {
|
||||
@@ -193,7 +194,7 @@ func (m *Model) InSyncSize() (files, bytes int) {
|
||||
defer m.RUnlock()
|
||||
|
||||
for n, f := range m.local {
|
||||
if gf, ok := m.global[n]; ok && f.Modified == gf.Modified {
|
||||
if gf, ok := m.global[n]; ok && f.Equals(gf) {
|
||||
files++
|
||||
bytes += f.Size()
|
||||
}
|
||||
@@ -249,7 +250,7 @@ func (m *Model) IndexUpdate(nodeID string, fs []protocol.FileInfo) {
|
||||
}
|
||||
|
||||
for _, f := range fs {
|
||||
if f.Flags&FlagDeleted != 0 && !m.delete {
|
||||
if f.Flags&protocol.FlagDeleted != 0 && !m.delete {
|
||||
// Files marked as deleted do not even enter the model
|
||||
continue
|
||||
}
|
||||
@@ -284,13 +285,16 @@ func (m *Model) Close(node string, err error) {
|
||||
func (m *Model) Request(nodeID, name string, offset uint64, size uint32, hash []byte) ([]byte, error) {
|
||||
// Verify that the requested file exists in the local and global model.
|
||||
m.RLock()
|
||||
_, localOk := m.local[name]
|
||||
lf, localOk := m.local[name]
|
||||
_, globalOk := m.global[name]
|
||||
m.RUnlock()
|
||||
if !localOk || !globalOk {
|
||||
log.Printf("SECURITY (nonexistent file) REQ(in): %s: %q o=%d s=%d h=%x", nodeID, name, offset, size, hash)
|
||||
return nil, ErrNoSuchFile
|
||||
}
|
||||
if lf.Flags&protocol.FlagInvalid != 0 {
|
||||
return nil, ErrInvalid
|
||||
}
|
||||
|
||||
if m.trace["net"] && nodeID != "<local>" {
|
||||
log.Printf("NET REQ(in): %s: %q o=%d s=%d h=%x", nodeID, name, offset, size, hash)
|
||||
@@ -322,7 +326,7 @@ func (m *Model) ReplaceLocal(fs []File) {
|
||||
|
||||
for _, f := range fs {
|
||||
newLocal[f.Name] = f
|
||||
if ef := m.local[f.Name]; ef.Modified != f.Modified {
|
||||
if ef := m.local[f.Name]; !ef.Equals(f) {
|
||||
updated = true
|
||||
}
|
||||
}
|
||||
@@ -430,7 +434,7 @@ func (m *Model) protocolIndex() []protocol.FileInfo {
|
||||
mf := fileInfoFromFile(f)
|
||||
if m.trace["idx"] {
|
||||
var flagComment string
|
||||
if mf.Flags&FlagDeleted != 0 {
|
||||
if mf.Flags&protocol.FlagDeleted != 0 {
|
||||
flagComment = " (deleted)"
|
||||
}
|
||||
log.Printf("IDX: %q m=%d f=%o%s (%d blocks)", mf.Name, mf.Modified, mf.Flags, flagComment, len(mf.Blocks))
|
||||
@@ -496,10 +500,10 @@ func (m *Model) markDeletedLocals(newLocal map[string]File) bool {
|
||||
var updated bool
|
||||
for n, f := range m.local {
|
||||
if _, ok := newLocal[n]; !ok {
|
||||
if gf := m.global[n]; gf.Modified <= f.Modified {
|
||||
if f.Flags&FlagDeleted == 0 {
|
||||
f.Flags = FlagDeleted
|
||||
f.Modified = f.Modified + 1
|
||||
if gf := m.global[n]; !gf.NewerThan(f) {
|
||||
if f.Flags&protocol.FlagDeleted == 0 {
|
||||
f.Flags = protocol.FlagDeleted
|
||||
f.Version++
|
||||
f.Blocks = nil
|
||||
updated = true
|
||||
}
|
||||
@@ -511,7 +515,7 @@ func (m *Model) markDeletedLocals(newLocal map[string]File) bool {
|
||||
}
|
||||
|
||||
func (m *Model) updateLocal(f File) {
|
||||
if ef, ok := m.local[f.Name]; !ok || ef.Modified != f.Modified {
|
||||
if ef, ok := m.local[f.Name]; !ok || !ef.Equals(f) {
|
||||
m.local[f.Name] = f
|
||||
m.recomputeGlobal()
|
||||
m.recomputeNeed()
|
||||
@@ -530,7 +534,7 @@ func (m *Model) recomputeGlobal() {
|
||||
|
||||
for _, fs := range m.remote {
|
||||
for n, f := range fs {
|
||||
if cf, ok := newGlobal[n]; !ok || cf.Modified < f.Modified {
|
||||
if cf, ok := newGlobal[n]; !ok || f.NewerThan(cf) {
|
||||
newGlobal[n] = f
|
||||
}
|
||||
}
|
||||
@@ -543,7 +547,7 @@ func (m *Model) recomputeGlobal() {
|
||||
updated = true
|
||||
} else {
|
||||
for n, f0 := range newGlobal {
|
||||
if f1, ok := m.global[n]; !ok || f0.Modified != f1.Modified {
|
||||
if f1, ok := m.global[n]; !ok || !f0.Equals(f1) {
|
||||
updated = true
|
||||
break
|
||||
}
|
||||
@@ -561,12 +565,16 @@ func (m *Model) recomputeNeed() {
|
||||
m.need = make(map[string]bool)
|
||||
for n, f := range m.global {
|
||||
hf, ok := m.local[n]
|
||||
if !ok || f.Modified > hf.Modified {
|
||||
if f.Flags&FlagDeleted != 0 && !m.delete {
|
||||
if !ok || f.NewerThan(hf) {
|
||||
if f.Flags&protocol.FlagInvalid != 0 {
|
||||
// Never attempt to sync invalid files
|
||||
continue
|
||||
}
|
||||
if f.Flags&protocol.FlagDeleted != 0 && !m.delete {
|
||||
// Don't want to delete files, so forget this need
|
||||
continue
|
||||
}
|
||||
if f.Flags&FlagDeleted != 0 && !ok {
|
||||
if f.Flags&protocol.FlagDeleted != 0 && !ok {
|
||||
// Don't have the file, so don't need to delete it
|
||||
continue
|
||||
}
|
||||
@@ -584,7 +592,7 @@ func (m *Model) whoHas(name string) []string {
|
||||
|
||||
gf := m.global[name]
|
||||
for node, files := range m.remote {
|
||||
if file, ok := files[name]; ok && file.Modified == gf.Modified {
|
||||
if file, ok := files[name]; ok && file.Equals(gf) {
|
||||
remote = append(remote, node)
|
||||
}
|
||||
}
|
||||
@@ -607,6 +615,7 @@ func fileFromFileInfo(f protocol.FileInfo) File {
|
||||
Name: f.Name,
|
||||
Flags: f.Flags,
|
||||
Modified: int64(f.Modified),
|
||||
Version: f.Version,
|
||||
Blocks: blocks,
|
||||
}
|
||||
}
|
||||
@@ -623,6 +632,7 @@ func fileInfoFromFile(f File) protocol.FileInfo {
|
||||
Name: f.Name,
|
||||
Flags: f.Flags,
|
||||
Modified: int64(f.Modified),
|
||||
Version: f.Version,
|
||||
Blocks: blocks,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user