mirror of
https://github.com/syncthing/syncthing.git
synced 2024-11-16 02:18:44 -07: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()
|
||||
seen := make(map[string]struct{})
|
||||
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 {
|
||||
seen[addr] = struct{}{}
|
||||
continue
|
||||
|
@ -208,8 +208,10 @@ func (c *globalClient) sendAnnouncement(timer *time.Timer) {
|
||||
}
|
||||
|
||||
if len(ann.Addresses) == 0 {
|
||||
c.setError(errors.New("nothing to announce"))
|
||||
l.Debugln("Nothing to announce")
|
||||
// There are legitimate cases for not having anything to announce,
|
||||
// yet still using global discovery for lookups. Do not error out
|
||||
// here.
|
||||
c.setError(nil)
|
||||
timer.Reset(announceErrorRetryInterval)
|
||||
return
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ func TestGlobalAnnounce(t *testing.T) {
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
func (c *localClient) announcementPkt() Announce {
|
||||
return Announce{
|
||||
ID: c.myID,
|
||||
Addresses: c.addrList.AllAddresses(),
|
||||
InstanceID: rand.Int63(),
|
||||
// announcementPkt appends the local discovery packet to send to msg. Returns
|
||||
// true if the packet should be sent, false if there is nothing useful to
|
||||
// send.
|
||||
func (c *localClient) announcementPkt(instanceID int64, msg []byte) ([]byte, bool) {
|
||||
addrs := c.addrList.AllAddresses()
|
||||
if len(addrs) == 0 {
|
||||
// Nothing to announce
|
||||
return msg, false
|
||||
}
|
||||
}
|
||||
|
||||
func (c *localClient) sendLocalAnnouncements() {
|
||||
msg := make([]byte, 4)
|
||||
if cap(msg) >= 4 {
|
||||
msg = msg[:4]
|
||||
} else {
|
||||
msg = make([]byte, 4)
|
||||
}
|
||||
binary.BigEndian.PutUint32(msg, Magic)
|
||||
|
||||
var pkt = c.announcementPkt()
|
||||
pkt := Announce{
|
||||
ID: c.myID,
|
||||
Addresses: addrs,
|
||||
InstanceID: instanceID,
|
||||
}
|
||||
bs, _ := pkt.Marshal()
|
||||
msg = append(msg, bs...)
|
||||
|
||||
return msg, true
|
||||
}
|
||||
|
||||
func (c *localClient) sendLocalAnnouncements() {
|
||||
var msg []byte
|
||||
var ok bool
|
||||
instanceID := rand.Int63()
|
||||
for {
|
||||
c.beacon.Send(msg)
|
||||
if msg, ok = c.announcementPkt(instanceID, msg[:0]); ok {
|
||||
c.beacon.Send(msg)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-c.localBcastTick:
|
||||
|
@ -7,13 +7,14 @@
|
||||
package discover
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
)
|
||||
|
||||
func TestRandomLocalInstanceID(t *testing.T) {
|
||||
func TestLocalInstanceID(t *testing.T) {
|
||||
c, err := NewLocal(protocol.LocalDeviceID, ":0", &fakeAddressLister{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -23,9 +24,15 @@ func TestRandomLocalInstanceID(t *testing.T) {
|
||||
|
||||
lc := c.(*localClient)
|
||||
|
||||
p0 := lc.announcementPkt()
|
||||
p1 := lc.announcementPkt()
|
||||
if p0.InstanceID == p1.InstanceID {
|
||||
p0, ok := lc.announcementPkt(1, nil)
|
||||
if !ok {
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user