aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tunnel
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2021-10-25 11:10:20 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2021-10-26 10:53:05 +0200
commitcfa231247a958ea7cdb89bd09043d93bcb8669db (patch)
treea4c9491d7a9316bc079306919160e250cb6041b5 /tunnel
parentdriver: format (diff)
downloadwireguard-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.go18
-rw-r--r--tunnel/service.go20
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