Repository: syncthing/syncthing (language: go)

Issue:
"No availabile source device" - sync is stuck
Me and a friend are sharing a folder. It worked fine for two weeks, now one file is stuck.
On my side the GUI says it's syncing 77% and that's not changing. No error messages.
The file is on my machine and the remote machine is unable to fetch it for some reason.

I have experienced numerous system crashes recently, maybe that could have caused the trouble?
I can remove that file, but it doesn't seem like a solution to me.

Here's a log from the friend's machine (I removed IPs, names and syncthing IDs):

```
[monitor] 16:37:17 INFO: Starting syncthing
[OCBUJ] 16:37:18 INFO: syncthing v0.10.30 (go1.4.2 linux-amd64 default) unknown-user@syncthing-builder 2015-03-29 07:46:44 UTC
[OCBUJ] 16:37:18 INFO: My ID: OCBUJGQ-[sensitive data]
[OCBUJ] 16:37:18 INFO: Starting web GUI on http://127.0.0.1:8080/
[OCBUJ] 16:37:18 INFO: Starting UPnP discovery...
[OCBUJ] 16:37:21 INFO: dial tcp: missing port in address 192.168.0.1
[OCBUJ] 16:37:24 INFO: UPnP discovery complete (found 0 devices).
[OCBUJ] 16:37:24 INFO: Starting local discovery announcements
[OCBUJ] 16:37:24 INFO: Starting global discovery announcements
[OCBUJ] 16:37:24 OK: Ready to synchronize [sensitive data] (read-write)
[OCBUJ] 16:37:24 INFO: Device OCBUJGQ-[sensitive data] is "[sensitive data]" at [dynamic]
[OCBUJ] 16:37:24 INFO: Device ZZMHPOP-[sensitive data] is "[sensitive data]" at [dynamic]
[OCBUJ] 16:37:24 INFO: Device 4B7NWP2-[sensitive data] is "[sensitive data]" at [dynamic]
[OCBUJ] 16:37:24 INFO: Starting usage reporting
[OCBUJ] 16:37:24 INFO: Completed initial scan (rw) of folder [sensitive data]
[OCBUJ] 16:38:00 INFO: Established secure connection to 4B7NWP2-[sensitive data] at 192.168.0.187:43360-109.[sensitive data]:13911
[OCBUJ] 16:38:00 INFO: Device 4B7NWP2-[sensitive data] client is "syncthing v0.10.30"
[OCBUJ] 16:38:00 INFO: Device 4B7NWP2-[sensitive data] name is "[sensitive data]"
[OCBUJ] 16:38:02 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:38:03 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:38:04 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:38:05 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:38:06 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:38:07 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:38:08 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:38:09 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:38:11 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:38:12 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:38:14 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:38:14 WARNING: Folder "[sensitive data]" isn't making progress - check logs for possible root cause. Pausing puller for 1m0s.
[OCBUJ] 16:39:15 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:39:16 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:39:17 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:39:18 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:39:19 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:39:20 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:39:21 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:39:22 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:39:23 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:39:24 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:39:25 INFO: Puller (folder "[sensitive data]", file "Unfa/unfa-01-23.wav"): pull: no available source device
[OCBUJ] 16:39:26 WARNING: Folder "[sensitive data]" isn't making progress - check logs for possible root cause. Pausing puller for 1m0s.
```



Discussion / hints:
Can you get the json values for:
`/rest/db/file?folder=<folder>&file=<full relative path to one of the out of sync files>`
from both sides?

What's that and how do I do that? Both sides run GNU/Linux.

Btw. the issue somehow resloved itself in the meantime.

Well that that probably just means that the file was changing while syncthing was trying to get it in sync.

Hmm but that lasted for an hour, while I wasn't doing anything with the file.

How fast that get's picked up repends on the rescan interval.

It's set to 5 seconds.

2015-04-11 20:08 GMT+02:00 Audrius Butkevicius notifications@github.com:

> How fast that get's picked up repends on the rescan interval.
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/syncthing/syncthing/issues/1628#issuecomment-91893924
> .

## 

Tobiasz _unfa_

-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GIT/MU/P d->-- s+:-(--)> a? C++(+++)>$ ULC+(++)>$ !P? L+++>++++$ E? W++>$
!N-? !o--? K-? !w-- O? !M-- V? PS++ PE++ !Y+ !PGP+? !t(+) 5? !X !R+ tv
b+>+++ DI>+ D+ G e h-->- !r y--()
------END GEEK CODE BLOCK------

If the file changed without the modification time or size changing, we would not pick up the new contents and the error would persist...


Fix patch:
diff --git a/lib/beacon/broadcast.go b/lib/beacon/broadcast.go
index e580bb7f1b7..6a4a05e16f9 100644
--- a/lib/beacon/broadcast.go
+++ b/lib/beacon/broadcast.go
@@ -46,8 +46,9 @@ func writeBroadcasts(ctx context.Context, inbox <-chan []byte, port int) error {
 
 		intfs, err := net.Interfaces()
 		if err != nil {
-			l.Debugln(err)
-			return err
+			l.Debugln("Failed to list interfaces:", err)
+			// net.Interfaces() is broken on Android. see https://github.com/golang/go/issues/40569
+			// Use the general broadcast address 255.255.255.255 instead.
 		}
 
 		var dsts []net.IP
@@ -58,8 +59,9 @@ func writeBroadcasts(ctx context.Context, inbox <-chan []byte, port int) error {
 
 			addrs, err := intf.Addrs()
 			if err != nil {
-				l.Debugln(err)
-				return err
+				l.Debugln("Failed to list interface addresses:", err)
+				// Interface discovery might work while retrieving the addresses doesn't. So log the error and carry on.
+				continue
 			}
 
 			for _, addr := range addrs {
diff --git a/lib/discover/local.go b/lib/discover/local.go
index ba950f4413c..a64c218a19b 100644
--- a/lib/discover/local.go
+++ b/lib/discover/local.go
@@ -110,11 +110,8 @@ func (c *localClient) Error() error {
 func (c *localClient) announcementPkt(instanceID int64, msg []byte) ([]byte, bool) {
 	addrs := c.addrList.AllAddresses()
 
-	// The list of all addresses can include unspecified addresses intended
-	// for a discovery server to complete, based on the packet source. We
-	// don't do that for local discovery, so filter out addresses that are
-	// usable as-is.
-	addrs = filterUnspecifiedLocal(addrs)
+	// remove all addresses which are not dialable
+	addrs = filterUndialableLocal(addrs)
 
 	// do not leak relay tokens to discovery
 	addrs = sanitizeRelayAddresses(addrs)
@@ -266,7 +263,7 @@ func (c *localClient) registerDevice(src net.Addr, device Announce) bool {
 				continue
 			}
 			u.Host = net.JoinHostPort(host, strconv.Itoa(tcpAddr.Port))
-			l.Debugf("discover: Reconstructed URL is %#v", u)
+			l.Debugf("discover: Reconstructed URL is %v", u)
 			validAddresses = append(validAddresses, u.String())
 			l.Debugf("discover: Replaced address %v in %s to get %s", tcpAddr.IP, addr, u.String())
 		} else {
@@ -292,9 +289,9 @@ func (c *localClient) registerDevice(src net.Addr, device Announce) bool {
 	return isNewDevice
 }
 
-// filterUnspecifiedLocal returns the list of addresses after removing any
-// unspecified, localhost, multicast, broadcast or port-zero addresses.
-func filterUnspecifiedLocal(addrs []string) []string {
+// filterUndialableLocal returns the list of addresses after removing any
+// localhost, multicast, broadcast or port-zero addresses.
+func filterUndialableLocal(addrs []string) []string {
 	filtered := addrs[:0]
 	for _, addr := range addrs {
 		u, err := url.Parse(addr)
@@ -310,9 +307,7 @@ func filterUnspecifiedLocal(addrs []string) []string {
 		switch {
 		case len(tcpAddr.IP) == 0:
 		case tcpAddr.Port == 0:
-		case tcpAddr.IP.IsUnspecified():
-		case !tcpAddr.IP.IsGlobalUnicast() && !tcpAddr.IP.IsLinkLocalUnicast():
-		default:
+		case tcpAddr.IP.IsGlobalUnicast(), tcpAddr.IP.IsLinkLocalUnicast(), tcpAddr.IP.IsUnspecified():
 			filtered = append(filtered, addr)
 		}
 	}


Test patch:
diff --git a/lib/discover/local_test.go b/lib/discover/local_test.go
index 6f78e095778..7fe0649dc9f 100644
--- a/lib/discover/local_test.go
+++ b/lib/discover/local_test.go
@@ -91,14 +91,14 @@ func TestLocalInstanceIDShouldTriggerNew(t *testing.T) {
 	}
 }
 
-func TestFilterUnspecified(t *testing.T) {
+func TestFilterUndialable(t *testing.T) {
 	addrs := []string{
 		"quic://[2001:db8::1]:22000",             // OK
 		"tcp://192.0.2.42:22000",                 // OK
 		"quic://[2001:db8::1]:0",                 // remove, port zero
 		"tcp://192.0.2.42:0",                     // remove, port zero
-		"quic://[::]:22000",                      // remove, unspecified
-		"tcp://0.0.0.0:22000",                    // remove, unspecified
+		"quic://[::]:22000",                      // OK
+		"tcp://0.0.0.0:22000",                    // OK
 		"tcp://[2001:db8::1]",                    // remove, no port
 		"tcp://192.0.2.42",                       // remove, no port
 		"tcp://foo:bar",                          // remove, host/port does not resolve
@@ -112,11 +112,13 @@ func TestFilterUnspecified(t *testing.T) {
 	exp := []string{
 		"quic://[2001:db8::1]:22000",
 		"tcp://192.0.2.42:22000",
+		"quic://[::]:22000",
+		"tcp://0.0.0.0:22000",
 		"tcp://[fe80::9ef:dff1:b332:5e56]:55681",
 	}
-	res := filterUnspecifiedLocal(addrs)
+	res := filterUndialableLocal(addrs)
 	if fmt.Sprint(res) != fmt.Sprint(exp) {
 		t.Log(res)
-		t.Error("filterUnspecified returned invalid addresses")
+		t.Error("filterUndialableLocal returned invalid addresses")
 	}
 }