diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-10-25 11:10:20 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-10-26 10:53:05 +0200 |
commit | cfa231247a958ea7cdb89bd09043d93bcb8669db (patch) | |
tree | a4c9491d7a9316bc079306919160e250cb6041b5 /tunnel | |
parent | driver: format (diff) | |
download | wireguard-windows-cfa231247a958ea7cdb89bd09043d93bcb8669db.tar.xz wireguard-windows-cfa231247a958ea7cdb89bd09043d93bcb8669db.zip |
tunnel: defer startup until tcp configuration is set
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'tunnel')
-rw-r--r-- | tunnel/interfacewatcher.go | 18 | ||||
-rw-r--r-- | tunnel/service.go | 20 |
2 files changed, 31 insertions, 7 deletions
diff --git a/tunnel/interfacewatcher.go b/tunnel/interfacewatcher.go index 5ca2c69d..f3dbc46a 100644 --- a/tunnel/interfacewatcher.go +++ b/tunnel/interfacewatcher.go @@ -6,9 +6,11 @@ package tunnel import ( + "errors" "fmt" "log" "sync" + "time" "golang.org/x/sys/windows" "golang.zx2c4.com/wireguard/windows/conf" @@ -27,7 +29,8 @@ type interfaceWatcherEvent struct { family winipcfg.AddressFamily } type interfaceWatcher struct { - errors chan interfaceWatcherError + errors chan interfaceWatcherError + started chan winipcfg.AddressFamily conf *conf.Config adapter *driver.Adapter @@ -38,9 +41,11 @@ type interfaceWatcher struct { changeCallbacks4 []winipcfg.ChangeCallback changeCallbacks6 []winipcfg.ChangeCallback storedEvents []interfaceWatcherEvent + watchdog *time.Timer } func (iw *interfaceWatcher) setup(family winipcfg.AddressFamily) { + iw.watchdog.Stop() var changeCallbacks *[]winipcfg.ChangeCallback var ipversion string if family == windows.AF_INET { @@ -75,12 +80,19 @@ func (iw *interfaceWatcher) setup(family winipcfg.AddressFamily) { iw.errors <- interfaceWatcherError{services.ErrorSetNetConfig, err} return } + + iw.started <- family } func watchInterface() (*interfaceWatcher, error) { iw := &interfaceWatcher{ - errors: make(chan interfaceWatcherError, 2), + errors: make(chan interfaceWatcherError, 2), + started: make(chan winipcfg.AddressFamily, 4), } + iw.watchdog = time.AfterFunc(time.Duration(1<<63-1), func() { + iw.errors <- interfaceWatcherError{services.ErrorCreateNetworkAdapter, errors.New("TCP/IP interface for adapter did not appear after one minute")} + }) + iw.watchdog.Stop() var err error iw.interfaceChangeCallback, err = winipcfg.RegisterInterfaceChangeCallback(func(notificationType winipcfg.MibNotificationType, iface *winipcfg.MibIPInterfaceRow) { iw.setupMutex.Lock() @@ -119,6 +131,7 @@ func watchInterface() (*interfaceWatcher, error) { func (iw *interfaceWatcher) Configure(adapter *driver.Adapter, conf *conf.Config, luid winipcfg.LUID) { iw.setupMutex.Lock() defer iw.setupMutex.Unlock() + iw.watchdog.Reset(time.Minute) iw.adapter, iw.conf, iw.luid = adapter, conf, luid for _, event := range iw.storedEvents { @@ -131,6 +144,7 @@ func (iw *interfaceWatcher) Configure(adapter *driver.Adapter, conf *conf.Config func (iw *interfaceWatcher) Destroy() { iw.setupMutex.Lock() + iw.watchdog.Stop() changeCallbacks4 := iw.changeCallbacks4 changeCallbacks6 := iw.changeCallbacks6 interfaceChangeCallback := iw.interfaceChangeCallback diff --git a/tunnel/service.go b/tunnel/service.go index 5680d0fc..24df3dfe 100644 --- a/tunnel/service.go +++ b/tunnel/service.go @@ -31,7 +31,8 @@ type tunnelService struct { } func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (svcSpecificEC bool, exitCode uint32) { - changes <- svc.Status{State: svc.StartPending} + serviceState := svc.StartPending + changes <- svc.Status{State: serviceState} var watcher *interfaceWatcher var adapter *driver.Adapter @@ -46,7 +47,8 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest, if logErr != nil { log.Println(logErr) } - changes <- svc.Status{State: svc.StopPending} + serviceState = svc.StopPending + changes <- svc.Status{State: serviceState} stopIt := make(chan bool, 1) go func() { @@ -127,7 +129,8 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest, * announce that we're running before starting additional services. */ log.Printf("SCM locked for %v by %s, marking service as started", lockStatus.Age, lockStatus.Owner) - changes <- svc.Status{State: svc.Running} + serviceState = svc.Running + changes <- svc.Status{State: serviceState} } m.Disconnect() } @@ -214,9 +217,9 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest, return } - changes <- svc.Status{State: svc.Running, Accepts: svc.AcceptStop | svc.AcceptShutdown} - log.Println("Startup complete") + changes <- svc.Status{State: serviceState, Accepts: svc.AcceptStop | svc.AcceptShutdown} + var started bool for { select { case c := <-r: @@ -228,6 +231,13 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest, default: log.Printf("Unexpected service control request #%d\n", c) } + case <-watcher.started: + if !started { + serviceState = svc.Running + changes <- svc.Status{State: serviceState, Accepts: svc.AcceptStop | svc.AcceptShutdown} + log.Println("Startup complete") + started = true + } case e := <-watcher.errors: serviceError, err = e.serviceError, e.err return |