Add external address tracker object

This commit is contained in:
Jakob Borg
2015-09-12 21:59:15 +02:00
parent 8779f93746
commit e694c664e5
10 changed files with 248 additions and 92 deletions

View File

@@ -15,6 +15,7 @@ import (
"time"
"github.com/syncthing/protocol"
"github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/sync"
)
@@ -113,44 +114,24 @@ func (d *UDPClient) broadcast() {
}
timer := time.NewTimer(0)
eventSub := events.Default.Subscribe(events.ExternalPortMappingChanged)
defer events.Default.Unsubscribe(eventSub)
for {
select {
case <-d.stop:
return
case <-eventSub.C():
ok := d.sendAnnouncement(remote, conn)
d.mut.Lock()
d.status = ok
d.mut.Unlock()
case <-timer.C:
var ok bool
if debug {
l.Debugf("discover %s: broadcast: Sending self announcement to %v", d.url, remote)
}
ann := d.announcer.Announcement()
pkt, err := ann.MarshalXDR()
if err != nil {
timer.Reset(d.errorRetryInterval)
continue
}
_, err = conn.WriteTo(pkt, remote)
if err != nil {
if debug {
l.Debugf("discover %s: broadcast: Failed to send self announcement: %s", d.url, err)
}
ok = false
} else {
// Verify that the announce server responds positively for our device ID
time.Sleep(1 * time.Second)
pkt, err := d.Lookup(protocol.DeviceIDFromBytes(ann.This.ID))
if err != nil && debug {
l.Debugf("discover %s: broadcast: Self-lookup failed: %v", d.url, err)
} else if debug {
l.Debugf("discover %s: broadcast: Self-lookup returned: %v", d.url, pkt.This.Addresses)
}
ok = len(pkt.This.Addresses) > 0
}
ok := d.sendAnnouncement(remote, conn)
d.mut.Lock()
d.status = ok
@@ -165,6 +146,40 @@ func (d *UDPClient) broadcast() {
}
}
func (d *UDPClient) sendAnnouncement(remote net.Addr, conn *net.UDPConn) bool {
if debug {
l.Debugf("discover %s: broadcast: Sending self announcement to %v", d.url, remote)
}
ann := d.announcer.Announcement()
pkt, err := ann.MarshalXDR()
if err != nil {
return false
}
myID := protocol.DeviceIDFromBytes(ann.This.ID)
_, err = conn.WriteTo(pkt, remote)
if err != nil {
if debug {
l.Debugf("discover %s: broadcast: Failed to send self announcement: %s", d.url, err)
}
return false
}
// Verify that the announce server responds positively for our device ID
time.Sleep(1 * time.Second)
ann, err = d.Lookup(myID)
if err != nil && debug {
l.Debugf("discover %s: broadcast: Self-lookup failed: %v", d.url, err)
} else if debug {
l.Debugf("discover %s: broadcast: Self-lookup returned: %v", d.url, ann.This.Addresses)
}
return len(ann.This.Addresses) > 0
}
func (d *UDPClient) Lookup(device protocol.DeviceID) (Announce, error) {
extIP, err := net.ResolveUDPAddr(d.url.Scheme, d.url.Host)
if err != nil {

View File

@@ -33,7 +33,7 @@ type Discoverer struct {
cacheLifetime time.Duration
negCacheCutoff time.Duration
beacons []beacon.Interface
extPort uint16
extAddr externalAddr
localBcastTick <-chan time.Time
forcedBcastTick chan time.Time
@@ -50,6 +50,10 @@ type relayStatusProvider interface {
ClientStatus() map[string]bool
}
type externalAddr interface {
ExternalAddresses() []string
}
type CacheEntry struct {
Address string
Seen time.Time
@@ -115,7 +119,7 @@ func (d *Discoverer) startLocalIPv6Multicasts(localMCAddr string) {
go d.recvAnnouncements(mb)
}
func (d *Discoverer) StartGlobal(servers []string, extPort uint16) {
func (d *Discoverer) StartGlobal(servers []string, extAddr externalAddr) {
d.mut.Lock()
defer d.mut.Unlock()
@@ -123,7 +127,7 @@ func (d *Discoverer) StartGlobal(servers []string, extPort uint16) {
d.stopGlobal()
}
d.extPort = extPort
d.extAddr = extAddr
wg := sync.NewWaitGroup()
clients := make(chan Client, len(servers))
for _, address := range servers {
@@ -303,8 +307,8 @@ func (d *Discoverer) Announcement() Announce {
func (d *Discoverer) announcementPkt(allowExternal bool) Announce {
var addrs []string
if d.extPort != 0 && allowExternal {
addrs = []string{fmt.Sprintf("tcp://:%d", d.extPort)}
if allowExternal && d.extAddr != nil {
addrs = d.extAddr.ExternalAddresses()
} else {
addrs = resolveAddrs(d.listenAddrs)
}

View File

@@ -103,7 +103,7 @@ func TestGlobalDiscovery(t *testing.T) {
"test1://23.23.23.23:234",
"test2://234.234.234.234.2345",
}
d.StartGlobal(servers, 1234)
d.StartGlobal(servers, nil)
if len(d.clients) != 3 {
t.Fatal("Wrong number of clients")