lib/connections, lib/nat: Correctly dis-/enable nat (fixes #6552) (#6719)

This commit is contained in:
Simon Frei 2020-06-07 20:29:53 +02:00 committed by GitHub
parent 74ea9c5f67
commit 3065b127b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 12 deletions

View File

@ -123,7 +123,6 @@ type service struct {
tlsDefaultCommonName string tlsDefaultCommonName string
limiter *limiter limiter *limiter
natService *nat.Service natService *nat.Service
natServiceToken *suture.ServiceToken
evLogger events.Logger evLogger events.Logger
listenersMut sync.RWMutex listenersMut sync.RWMutex
@ -188,6 +187,7 @@ func NewService(cfg config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *t
service.Add(util.AsService(service.connect, fmt.Sprintf("%s/connect", service))) service.Add(util.AsService(service.connect, fmt.Sprintf("%s/connect", service)))
service.Add(util.AsService(service.handle, fmt.Sprintf("%s/handle", service))) service.Add(util.AsService(service.handle, fmt.Sprintf("%s/handle", service)))
service.Add(service.listenerSupervisor) service.Add(service.listenerSupervisor)
service.Add(service.natService)
return service return service
} }
@ -652,16 +652,6 @@ func (s *service) CommitConfiguration(from, to config.Configuration) bool {
} }
s.listenersMut.Unlock() s.listenersMut.Unlock()
if to.Options.NATEnabled && s.natServiceToken == nil {
l.Debugln("Starting NAT service")
token := s.Add(s.natService)
s.natServiceToken = &token
} else if !to.Options.NATEnabled && s.natServiceToken != nil {
l.Debugln("Stopping NAT service")
s.Remove(*s.natServiceToken)
s.natServiceToken = nil
}
return true return true
} }

View File

@ -45,9 +45,36 @@ func NewService(id protocol.DeviceID, cfg config.Wrapper) *Service {
mut: sync.NewRWMutex(), mut: sync.NewRWMutex(),
} }
s.Service = util.AsService(s.serve, s.String()) s.Service = util.AsService(s.serve, s.String())
cfg.Subscribe(s)
return s return s
} }
func (s *Service) VerifyConfiguration(from, to config.Configuration) error {
return nil
}
func (s *Service) CommitConfiguration(from, to config.Configuration) bool {
if !from.Options.NATEnabled && to.Options.NATEnabled {
s.mut.Lock()
l.Debugln("Starting NAT service")
s.timer.Reset(0)
s.mut.Unlock()
} else if from.Options.NATEnabled && !to.Options.NATEnabled {
s.mut.Lock()
l.Debugln("Stopping NAT service")
if !s.timer.Stop() {
<-s.timer.C
}
s.mut.Unlock()
}
return true
}
func (s *Service) Stop() {
s.cfg.Unsubscribe(s)
s.Service.Stop()
}
func (s *Service) serve(ctx context.Context) { func (s *Service) serve(ctx context.Context) {
announce := stdsync.Once{} announce := stdsync.Once{}

View File

@ -7,9 +7,13 @@
package nat package nat
import ( import (
"io/ioutil"
"net" "net"
"os"
"testing" "testing"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/protocol" "github.com/syncthing/syncthing/lib/protocol"
) )
@ -56,7 +60,15 @@ func TestMappingValidGateway(t *testing.T) {
} }
func TestMappingClearAddresses(t *testing.T) { func TestMappingClearAddresses(t *testing.T) {
natSvc := NewService(protocol.EmptyDeviceID, nil) tmpFile, err := ioutil.TempFile("", "syncthing-testConfig-")
if err != nil {
t.Fatal(err)
}
w := config.Wrap(tmpFile.Name(), config.Configuration{}, events.NoopLogger)
defer os.RemoveAll(tmpFile.Name())
tmpFile.Close()
natSvc := NewService(protocol.EmptyDeviceID, w)
// Mock a mapped port; avoids the need to actually map a port // Mock a mapped port; avoids the need to actually map a port
ip := net.ParseIP("192.168.0.1") ip := net.ParseIP("192.168.0.1")
m := natSvc.NewMapping(TCP, ip, 1024) m := natSvc.NewMapping(TCP, ip, 1024)