mirror of
https://github.com/octoleo/syncthing.git
synced 2025-02-08 23:08:27 +00:00
Fix discovery in the absence of listen addresses (fixes #4418)
This makes it OK to not have any listeners working. Specifically, - We don't complain about an empty listener address - We don't complain about not having anything to announce to global discovery servers - We don't send local discovery packets when there is nothing to announce. The last point also fixes a thing where the list of addresses for local discovery was set at startup time and never refreshed. GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4517
This commit is contained in:
parent
aecd7c64ce
commit
7ebf58f1bc
@ -504,6 +504,13 @@ func (s *Service) CommitConfiguration(from, to config.Configuration) bool {
|
|||||||
s.listenersMut.Lock()
|
s.listenersMut.Lock()
|
||||||
seen := make(map[string]struct{})
|
seen := make(map[string]struct{})
|
||||||
for _, addr := range config.Wrap("", to).ListenAddresses() {
|
for _, addr := range config.Wrap("", to).ListenAddresses() {
|
||||||
|
if addr == "" {
|
||||||
|
// We can get an empty address if there is an empty listener
|
||||||
|
// element in the config, indicating no listeners should be
|
||||||
|
// used. This is not an error.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if _, ok := s.listeners[addr]; ok {
|
if _, ok := s.listeners[addr]; ok {
|
||||||
seen[addr] = struct{}{}
|
seen[addr] = struct{}{}
|
||||||
continue
|
continue
|
||||||
|
@ -208,8 +208,10 @@ func (c *globalClient) sendAnnouncement(timer *time.Timer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(ann.Addresses) == 0 {
|
if len(ann.Addresses) == 0 {
|
||||||
c.setError(errors.New("nothing to announce"))
|
// There are legitimate cases for not having anything to announce,
|
||||||
l.Debugln("Nothing to announce")
|
// yet still using global discovery for lookups. Do not error out
|
||||||
|
// here.
|
||||||
|
c.setError(nil)
|
||||||
timer.Reset(announceErrorRetryInterval)
|
timer.Reset(announceErrorRetryInterval)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ func TestGlobalAnnounce(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !strings.Contains(string(s.announce), "tcp://0.0.0.0:22000") {
|
if !strings.Contains(string(s.announce), "tcp://0.0.0.0:22000") {
|
||||||
t.Errorf("announce missing addresses address: %s", s.announce)
|
t.Errorf("announce missing address: %q", s.announce)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,24 +112,42 @@ func (c *localClient) Error() error {
|
|||||||
return c.beacon.Error()
|
return c.beacon.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *localClient) announcementPkt() Announce {
|
// announcementPkt appends the local discovery packet to send to msg. Returns
|
||||||
return Announce{
|
// true if the packet should be sent, false if there is nothing useful to
|
||||||
ID: c.myID,
|
// send.
|
||||||
Addresses: c.addrList.AllAddresses(),
|
func (c *localClient) announcementPkt(instanceID int64, msg []byte) ([]byte, bool) {
|
||||||
InstanceID: rand.Int63(),
|
addrs := c.addrList.AllAddresses()
|
||||||
|
if len(addrs) == 0 {
|
||||||
|
// Nothing to announce
|
||||||
|
return msg, false
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func (c *localClient) sendLocalAnnouncements() {
|
if cap(msg) >= 4 {
|
||||||
msg := make([]byte, 4)
|
msg = msg[:4]
|
||||||
|
} else {
|
||||||
|
msg = make([]byte, 4)
|
||||||
|
}
|
||||||
binary.BigEndian.PutUint32(msg, Magic)
|
binary.BigEndian.PutUint32(msg, Magic)
|
||||||
|
|
||||||
var pkt = c.announcementPkt()
|
pkt := Announce{
|
||||||
|
ID: c.myID,
|
||||||
|
Addresses: addrs,
|
||||||
|
InstanceID: instanceID,
|
||||||
|
}
|
||||||
bs, _ := pkt.Marshal()
|
bs, _ := pkt.Marshal()
|
||||||
msg = append(msg, bs...)
|
msg = append(msg, bs...)
|
||||||
|
|
||||||
|
return msg, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *localClient) sendLocalAnnouncements() {
|
||||||
|
var msg []byte
|
||||||
|
var ok bool
|
||||||
|
instanceID := rand.Int63()
|
||||||
for {
|
for {
|
||||||
c.beacon.Send(msg)
|
if msg, ok = c.announcementPkt(instanceID, msg[:0]); ok {
|
||||||
|
c.beacon.Send(msg)
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-c.localBcastTick:
|
case <-c.localBcastTick:
|
||||||
|
@ -7,13 +7,14 @@
|
|||||||
package discover
|
package discover
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRandomLocalInstanceID(t *testing.T) {
|
func TestLocalInstanceID(t *testing.T) {
|
||||||
c, err := NewLocal(protocol.LocalDeviceID, ":0", &fakeAddressLister{})
|
c, err := NewLocal(protocol.LocalDeviceID, ":0", &fakeAddressLister{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -23,9 +24,15 @@ func TestRandomLocalInstanceID(t *testing.T) {
|
|||||||
|
|
||||||
lc := c.(*localClient)
|
lc := c.(*localClient)
|
||||||
|
|
||||||
p0 := lc.announcementPkt()
|
p0, ok := lc.announcementPkt(1, nil)
|
||||||
p1 := lc.announcementPkt()
|
if !ok {
|
||||||
if p0.InstanceID == p1.InstanceID {
|
t.Fatal("unexpectedly not ok")
|
||||||
|
}
|
||||||
|
p1, ok := lc.announcementPkt(2, nil)
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("unexpectedly not ok")
|
||||||
|
}
|
||||||
|
if bytes.Equal(p0, p1) {
|
||||||
t.Error("each generated packet should have a new instance id")
|
t.Error("each generated packet should have a new instance id")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user