diff options
author | 2021-09-11 23:24:22 +0200 | |
---|---|---|
committer | 2021-10-16 22:55:24 -0600 | |
commit | 548405e21b87d982a2d2094ce565bac5ac3c308a (patch) | |
tree | 6843727e22985d3cd08cd76ee47868d2e53fd2cc | |
parent | manager: remove legacy store support (diff) | |
download | wireguard-windows-548405e21b87d982a2d2094ce565bac5ac3c308a.tar.xz wireguard-windows-548405e21b87d982a2d2094ce565bac5ac3c308a.zip |
global: remove wireguard-go/Wintun implementation
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r-- | Makefile | 19 | ||||
-rw-r--r-- | build.bat | 5 | ||||
-rw-r--r-- | conf/config.go | 5 | ||||
-rw-r--r-- | conf/parser.go | 164 | ||||
-rw-r--r-- | conf/writer.go | 35 | ||||
-rw-r--r-- | docs/adminregistry.md | 14 | ||||
-rw-r--r-- | go.mod | 1 | ||||
-rw-r--r-- | go.mod.master | 1 | ||||
-rw-r--r-- | go.sum | 3 | ||||
-rw-r--r-- | main.go | 11 | ||||
-rw-r--r-- | manager/ipc_server.go | 74 | ||||
-rw-r--r-- | manager/ipc_uapi.go | 71 | ||||
-rw-r--r-- | manager/service.go | 6 | ||||
-rw-r--r-- | manager/tunneltracker.go | 1 | ||||
-rw-r--r-- | resources.rc | 1 | ||||
-rw-r--r-- | services/errors.go | 3 | ||||
-rw-r--r-- | tunnel/addressconfig.go | 5 | ||||
-rw-r--r-- | tunnel/defaultroutemonitor.go | 159 | ||||
-rw-r--r-- | tunnel/interfacewatcher.go | 79 | ||||
-rw-r--r-- | tunnel/ipcpermissions.go | 63 | ||||
-rw-r--r-- | tunnel/service.go | 164 | ||||
-rw-r--r-- | tunnel/winipcfg/winipcfg_test.go | 4 | ||||
-rw-r--r-- | tunnel/wintun_test.go | 202 |
23 files changed, 85 insertions, 1005 deletions
@@ -1,4 +1,4 @@ -GOFLAGS := -tags load_wintun_from_rsrc,load_wgnt_from_rsrc -ldflags="-H windowsgui -s -w" -v -trimpath +GOFLAGS := -tags load_wgnt_from_rsrc -ldflags="-H windowsgui -s -w" -v -trimpath export GOOS := windows export PATH := $(CURDIR)/.deps/go/bin:$(PATH) @@ -10,7 +10,7 @@ RCFLAGS := -DWIREGUARD_VERSION_ARRAY=$(subst $(space),$(comma),$(wordlist 1,4,$( rwildcard=$(foreach d,$(filter-out .deps,$(wildcard $1*)),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) SOURCE_FILES := $(call rwildcard,,*.go) .deps/go/prepared go.mod go.sum -RESOURCE_FILES := resources.rc version/version.go manifest.xml $(patsubst %.svg,%.ico,$(wildcard ui/icon/*.svg)) .deps/wintun/prepared .deps/wireguard-nt/prepared +RESOURCE_FILES := resources.rc version/version.go manifest.xml $(patsubst %.svg,%.ico,$(wildcard ui/icon/*.svg)) .deps/wireguard-nt/prepared DEPLOYMENT_HOST ?= winvm DEPLOYMENT_PATH ?= Desktop @@ -26,7 +26,6 @@ define download = endef $(eval $(call download,go.tar.gz,https://golang.org/dl/go1.17.2.linux-amd64.tar.gz,f242a9db6a0ad1846de7b6d94d507915d14062660616a61ef7c808a76e4f1676)) -$(eval $(call download,wintun.zip,https://www.wintun.net/builds/wintun-0.14.1.zip,07c256185d6ee3652e09fa55c0b673e2624b565e02c4b9091c79ca7d2f24ef51)) $(eval $(call download,wireguard-nt.zip,https://download.wireguard.com/wireguard-nt/wireguard-nt-0.10.1.zip,772c0b1463d8d2212716f43f06f4594d880dea4f735165bd68e388fc41b81605)) .deps/go/prepared: .distfiles/go.tar.gz $(wildcard go-patches/*.patch) @@ -37,12 +36,6 @@ $(eval $(call download,wireguard-nt.zip,https://download.wireguard.com/wireguard cat $(filter %.patch,$^) | patch -f -N -r- -p1 -d .deps/go touch $@ -.deps/wintun/prepared: .distfiles/wintun.zip - mkdir -p .deps - rm -rf .deps/wintun - bsdtar -C .deps -xf .distfiles/wintun.zip - touch $@ - .deps/wireguard-nt/prepared: .distfiles/wireguard-nt.zip mkdir -p .deps rm -rf .deps/wireguard-nt @@ -53,16 +46,16 @@ $(eval $(call download,wireguard-nt.zip,https://download.wireguard.com/wireguard convert -background none $< -define icon:auto-resize="256,192,128,96,64,48,40,32,24,20,16" -compress zip $@ resources_amd64.syso: $(RESOURCE_FILES) - x86_64-w64-mingw32-windres $(RCFLAGS) -I .deps/wintun/bin/amd64 -I .deps/wireguard-nt/bin/amd64 -i $< -o $@ + x86_64-w64-mingw32-windres $(RCFLAGS) -I .deps/wireguard-nt/bin/amd64 -i $< -o $@ resources_386.syso: $(RESOURCE_FILES) - i686-w64-mingw32-windres $(RCFLAGS) -I .deps/wintun/bin/x86 -I .deps/wireguard-nt/bin/x86 -i $< -o $@ + i686-w64-mingw32-windres $(RCFLAGS) -I .deps/wireguard-nt/bin/x86 -i $< -o $@ resources_arm.syso: $(RESOURCE_FILES) - armv7-w64-mingw32-windres $(RCFLAGS) -I .deps/wintun/bin/arm -I .deps/wireguard-nt/bin/arm -i $< -o $@ + armv7-w64-mingw32-windres $(RCFLAGS) -I .deps/wireguard-nt/bin/arm -i $< -o $@ resources_arm64.syso: $(RESOURCE_FILES) - aarch64-w64-mingw32-windres $(RCFLAGS) -I .deps/wintun/bin/arm64 -I .deps/wireguard-nt/bin/arm64 -i $< -o $@ + aarch64-w64-mingw32-windres $(RCFLAGS) -I .deps/wireguard-nt/bin/arm64 -i $< -o $@ amd64/wireguard.exe: export GOARCH := amd64 amd64/wireguard.exe: resources_amd64.syso $(SOURCE_FILES) @@ -23,7 +23,6 @@ if exist .deps\prepared goto :render call :download wireguard-tools.zip https://git.zx2c4.com/wireguard-tools/snapshot/wireguard-tools-1ee37b8e4833a25efe6f1fc0d5bdcb476148f4ba.zip ed0739bc3e5a7021a59d4cc4fc63e5fb60a0cb8628d30515a747bfbdcf1fdb0a "--exclude wg-quick --strip-components 1" || goto :error rem Mirror of https://sourceforge.net/projects/gnuwin32/files/patch/2.5.9-7/patch-2.5.9-7-bin.zip with fixed manifest call :download patch.zip https://download.wireguard.com/windows-toolchain/distfiles/patch-2.5.9-7-bin-fixed-manifest.zip 25977006ca9713f2662a5d0a2ed3a5a138225b8be3757035bd7da9dcf985d0a1 "--strip-components 1 bin" || goto :error - call :download wintun.zip https://www.wintun.net/builds/wintun-0.14.1.zip 07c256185d6ee3652e09fa55c0b673e2624b565e02c4b9091c79ca7d2f24ef51 || goto :error call :download wireguard-nt.zip https://download.wireguard.com/wireguard-nt/wireguard-nt-0.10.1.zip 772c0b1463d8d2212716f43f06f4594d880dea4f735165bd68e388fc41b81605 || goto :error echo [+] Patching go for %%a in ("..\go-patches\*.patch") do .\patch.exe -f -N -r- -d go -p1 --binary < "%%a" || goto :error @@ -77,9 +76,9 @@ if exist .deps\prepared goto :render set GOARCH=%~3 mkdir %1 >NUL 2>&1 echo [+] Assembling resources %1 - %~2-w64-mingw32-windres -I ".deps\wintun\bin\%~1" -I ".deps\wireguard-nt\bin\%~1" -DWIREGUARD_VERSION_ARRAY=%WIREGUARD_VERSION_ARRAY% -DWIREGUARD_VERSION_STR=%WIREGUARD_VERSION% -i resources.rc -o "resources_%~3.syso" -O coff -c 65001 || exit /b %errorlevel% + %~2-w64-mingw32-windres -I ".deps\wireguard-nt\bin\%~1" -DWIREGUARD_VERSION_ARRAY=%WIREGUARD_VERSION_ARRAY% -DWIREGUARD_VERSION_STR=%WIREGUARD_VERSION% -i resources.rc -o "resources_%~3.syso" -O coff -c 65001 || exit /b %errorlevel% echo [+] Building program %1 - go build -tags load_wintun_from_rsrc,load_wgnt_from_rsrc -ldflags="-H windowsgui -s -w" -trimpath -v -o "%~1\wireguard.exe" || exit /b 1 + go build -tags load_wgnt_from_rsrc -ldflags="-H windowsgui -s -w" -trimpath -v -o "%~1\wireguard.exe" || exit /b 1 if not exist "%~1\wg.exe" ( echo [+] Building command line tools %1 del .deps\src\*.exe .deps\src\*.o .deps\src\wincompat\*.o .deps\src\wincompat\*.lib 2> NUL diff --git a/conf/config.go b/conf/config.go index c764dfa9..b600456d 100644 --- a/conf/config.go +++ b/conf/config.go @@ -9,7 +9,6 @@ import ( "crypto/rand" "crypto/subtle" "encoding/base64" - "encoding/hex" "fmt" "net" "strings" @@ -146,10 +145,6 @@ func (k *Key) String() string { return base64.StdEncoding.EncodeToString(k[:]) } -func (k *Key) HexString() string { - return hex.EncodeToString(k[:]) -} - func (k *Key) IsZero() bool { var zeros Key return subtle.ConstantTimeCompare(zeros[:], k[:]) == 1 diff --git a/conf/parser.go b/conf/parser.go index 2a1c0894..83f25964 100644 --- a/conf/parser.go +++ b/conf/parser.go @@ -6,19 +6,15 @@ package conf import ( - "bufio" "encoding/base64" - "encoding/hex" - "io" "net" "strconv" "strings" - "time" "golang.org/x/sys/windows" "golang.org/x/text/encoding/unicode" - "golang.zx2c4.com/wireguard/windows/driver" + "golang.zx2c4.com/wireguard/windows/driver" "golang.zx2c4.com/wireguard/windows/l18n" ) @@ -162,27 +158,6 @@ func parseKeyBase64(s string) (*Key, error) { return &key, nil } -func parseKeyHex(s string) (*Key, error) { - k, err := hex.DecodeString(s) - if err != nil { - return nil, &ParseError{l18n.Sprintf("Invalid key: %v", err), s} - } - if len(k) != KeyLength { - return nil, &ParseError{l18n.Sprintf("Keys must decode to exactly 32 bytes"), s} - } - var key Key - copy(key[:], k) - return &key, nil -} - -func parseBytesOrStamp(s string) (uint64, error) { - b, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return 0, &ParseError{l18n.Sprintf("Number must be a number between 0 and 2^64-1: %v", err), s} - } - return b, nil -} - func splitList(s string) ([]string, error) { var out []string for _, split := range strings.Split(s, ",") { @@ -387,143 +362,6 @@ func FromWgQuickWithUnknownEncoding(s string, name string) (*Config, error) { return nil, firstErr } -func FromUAPI(reader io.Reader, existingConfig *Config) (*Config, error) { - parserState := inInterfaceSection - conf := Config{ - Name: existingConfig.Name, - Interface: Interface{ - Addresses: existingConfig.Interface.Addresses, - DNS: existingConfig.Interface.DNS, - DNSSearch: existingConfig.Interface.DNSSearch, - MTU: existingConfig.Interface.MTU, - PreUp: existingConfig.Interface.PreUp, - PostUp: existingConfig.Interface.PostUp, - PreDown: existingConfig.Interface.PreDown, - PostDown: existingConfig.Interface.PostDown, - TableOff: existingConfig.Interface.TableOff, - }, - } - var peer *Peer - lineReader := bufio.NewReader(reader) - for { - line, err := lineReader.ReadString('\n') - if err != nil { - return nil, err - } - line = line[:len(line)-1] - if len(line) == 0 { - break - } - equals := strings.IndexByte(line, '=') - if equals < 0 { - return nil, &ParseError{l18n.Sprintf("Config key is missing an equals separator"), line} - } - key, val := line[:equals], line[equals+1:] - if len(val) == 0 { - return nil, &ParseError{l18n.Sprintf("Key must have a value"), line} - } - switch key { - case "public_key": - conf.maybeAddPeer(peer) - peer = &Peer{} - parserState = inPeerSection - case "errno": - if val == "0" { - continue - } else { - return nil, &ParseError{l18n.Sprintf("Error in getting configuration"), val} - } - } - if parserState == inInterfaceSection { - switch key { - case "private_key": - k, err := parseKeyHex(val) - if err != nil { - return nil, err - } - conf.Interface.PrivateKey = *k - case "listen_port": - p, err := parsePort(val) - if err != nil { - return nil, err - } - conf.Interface.ListenPort = p - case "fwmark": - // Ignored for now. - - default: - return nil, &ParseError{l18n.Sprintf("Invalid key for interface section"), key} - } - } else if parserState == inPeerSection { - switch key { - case "public_key": - k, err := parseKeyHex(val) - if err != nil { - return nil, err - } - peer.PublicKey = *k - case "preshared_key": - k, err := parseKeyHex(val) - if err != nil { - return nil, err - } - peer.PresharedKey = *k - case "protocol_version": - if val != "1" { - return nil, &ParseError{l18n.Sprintf("Protocol version must be 1"), val} - } - case "allowed_ip": - a, err := parseIPCidr(val) - if err != nil { - return nil, err - } - peer.AllowedIPs = append(peer.AllowedIPs, *a) - case "persistent_keepalive_interval": - p, err := parsePersistentKeepalive(val) - if err != nil { - return nil, err - } - peer.PersistentKeepalive = p - case "endpoint": - e, err := parseEndpoint(val) - if err != nil { - return nil, err - } - peer.Endpoint = *e - case "tx_bytes": - b, err := parseBytesOrStamp(val) - if err != nil { - return nil, err - } - peer.TxBytes = Bytes(b) - case "rx_bytes": - b, err := parseBytesOrStamp(val) - if err != nil { - return nil, err - } - peer.RxBytes = Bytes(b) - case "last_handshake_time_sec": - t, err := parseBytesOrStamp(val) - if err != nil { - return nil, err - } - peer.LastHandshakeTime += HandshakeTime(time.Duration(t) * time.Second) - case "last_handshake_time_nsec": - t, err := parseBytesOrStamp(val) - if err != nil { - return nil, err - } - peer.LastHandshakeTime += HandshakeTime(time.Duration(t) * time.Nanosecond) - default: - return nil, &ParseError{l18n.Sprintf("Invalid key for peer section"), key} - } - } - } - conf.maybeAddPeer(peer) - - return &conf, nil -} - func FromDriverConfiguration(interfaze *driver.Interface, existingConfig *Config) *Config { conf := Config{ Name: existingConfig.Name, diff --git a/conf/writer.go b/conf/writer.go index 8749b2fd..3e24559f 100644 --- a/conf/writer.go +++ b/conf/writer.go @@ -91,41 +91,6 @@ func (conf *Config) ToWgQuick() string { return output.String() } -func (conf *Config) ToUAPI() string { - var output strings.Builder - output.WriteString(fmt.Sprintf("private_key=%s\n", conf.Interface.PrivateKey.HexString())) - - if conf.Interface.ListenPort > 0 { - output.WriteString(fmt.Sprintf("listen_port=%d\n", conf.Interface.ListenPort)) - } - - if len(conf.Peers) > 0 { - output.WriteString("replace_peers=true\n") - } - - for _, peer := range conf.Peers { - output.WriteString(fmt.Sprintf("public_key=%s\n", peer.PublicKey.HexString())) - - if !peer.PresharedKey.IsZero() { - output.WriteString(fmt.Sprintf("preshared_key=%s\n", peer.PresharedKey.HexString())) - } - - if !peer.Endpoint.IsEmpty() { - output.WriteString(fmt.Sprintf("endpoint=%s\n", peer.Endpoint.String())) - } - - output.WriteString(fmt.Sprintf("persistent_keepalive_interval=%d\n", peer.PersistentKeepalive)) - - if len(peer.AllowedIPs) > 0 { - output.WriteString("replace_allowed_ips=true\n") - for _, address := range peer.AllowedIPs { - output.WriteString(fmt.Sprintf("allowed_ip=%s\n", address.String())) - } - } - } - return output.String() -} - func (config *Config) ToDriverConfiguration() (*driver.Interface, uint32) { preallocation := unsafe.Sizeof(driver.Interface{}) + uintptr(len(config.Peers))*unsafe.Sizeof(driver.Peer{}) for i := range config.Peers { diff --git a/docs/adminregistry.md b/docs/adminregistry.md index bd13fee9..4289fb38 100644 --- a/docs/adminregistry.md +++ b/docs/adminregistry.md @@ -37,17 +37,3 @@ executing these scripts. ``` > reg add HKLM\Software\WireGuard /v DangerousScriptExecution /t REG_DWORD /d 1 /f ``` - -#### `HKLM\Software\WireGuard\UseUserspaceImplementation` - -When this key is set to `DWORD(1)`, the legacy wireguard-go/Wintun implementation -is used instead of the newer, faster [WireGuardNT](https://git.zx2c4.com/wireguard-nt/about/) -implementation. This is an intended stop-gap solution in case there are early bugs -with WireGuardNT, and this option will be removed after a short period. If you use -this option, please send an email to team@wireguard.com explaining the issues you -had with WireGuardNT, so that they can be fixed before this option goes away. If -you are not having issues, do not use this option. - -``` -> reg add HKLM\Software\WireGuard /v UseUserspaceImplementation /t REG_DWORD /d 1 /f -``` @@ -9,7 +9,6 @@ require ( golang.org/x/net v0.0.0-20211011170408-caeb26a5c8c0 golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b - golang.zx2c4.com/wireguard v0.0.0-20211012062646-82d2aa87aa62 ) require ( diff --git a/go.mod.master b/go.mod.master index ecda4c13..35d6a886 100644 --- a/go.mod.master +++ b/go.mod.master @@ -9,7 +9,6 @@ require ( golang.org/x/net latest golang.org/x/sys latest golang.org/x/text master - golang.zx2c4.com/wireguard master ) replace ( @@ -6,7 +6,6 @@ golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20211011170408-caeb26a5c8c0 h1:qOfNqBm5gk93LjGZo1MJaKY6Bph39zOKz1Hz2ogHj1w= golang.org/x/net v0.0.0-20211011170408-caeb26a5c8c0/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -24,8 +23,6 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.zx2c4.com/wireguard v0.0.0-20211012062646-82d2aa87aa62 h1:c39XZipaMOiSSqTCpqJmYgnzscTBGLFPgMmGvubmZ6E= -golang.zx2c4.com/wireguard v0.0.0-20211012062646-82d2aa87aa62/go.mod h1:id8Oh3eCCmpj9uVGWVjsUAl6UPX5ysMLzu6QxJU2UOU= golang.zx2c4.com/wireguard/windows v0.0.0-20210121140954-e7fc19d483bd h1:kAUzMAITME2MCtrXBaUa9P4tndiXGWO674k9gn6ZR28= golang.zx2c4.com/wireguard/windows v0.0.0-20210121140954-e7fc19d483bd/go.mod h1:Y+FYqVFaQO6a+1uigm0N0GiuaZrLEaBxEiJ8tfH9sMQ= golang.zx2c4.com/wireguard/windows v0.0.0-20210224134948-620c54ef6199 h1:ogXKLng/Myrt2odYTkleySGzQj/GWg9GV1AQ8P9NnU4= @@ -17,7 +17,6 @@ import ( "time" "golang.org/x/sys/windows" - "golang.zx2c4.com/wireguard/tun/wintun" "golang.zx2c4.com/wireguard/windows/conf" "golang.zx2c4.com/wireguard/windows/driver" @@ -319,13 +318,9 @@ func main() { if len(os.Args) != 2 { usage() } - err1 := driver.Uninstall() - err2 := wintun.Uninstall() - if err1 != nil { - fatal(err1) - } - if err2 != nil { - fatal(err2) + err := driver.Uninstall() + if err != nil { + fatal(err) } return } diff --git a/manager/ipc_server.go b/manager/ipc_server.go index e88ab7e4..504b5cce 100644 --- a/manager/ipc_server.go +++ b/manager/ipc_server.go @@ -47,64 +47,26 @@ func (s *ManagerService) StoredConfig(tunnelName string) (*conf.Config, error) { } func (s *ManagerService) RuntimeConfig(tunnelName string) (*conf.Config, error) { - if !conf.AdminBool("UseUserspaceImplementation") { - storedConfig, err := conf.LoadFromName(tunnelName) - if err != nil { - return nil, err - } - driverAdapter, err := findDriverAdapter(tunnelName) - if err != nil { - return nil, err - } - runtimeConfig, err := driverAdapter.Configuration() - if err != nil { - driverAdapter.Unlock() - releaseDriverAdapter(tunnelName) - return nil, err - } - conf := conf.FromDriverConfiguration(runtimeConfig, storedConfig) + storedConfig, err := conf.LoadFromName(tunnelName) + if err != nil { + return nil, err + } + driverAdapter, err := findDriverAdapter(tunnelName) + if err != nil { + return nil, err + } + runtimeConfig, err := driverAdapter.Configuration() + if err != nil { driverAdapter.Unlock() - if s.elevatedToken == 0 { - conf.Redact() - } - return conf, nil - } else { - storedConfig, err := conf.LoadFromName(tunnelName) - if err != nil { - return nil, err - } - pipe, err := connectTunnelServicePipe(tunnelName) - if err != nil { - return nil, err - } - pipe.SetDeadline(time.Now().Add(time.Second * 2)) - _, err = pipe.Write([]byte("get=1\n\n")) - if err == windows.ERROR_NO_DATA { - log.Println("IPC pipe closed unexpectedly, so reopening") - pipe.Unlock() - disconnectTunnelServicePipe(tunnelName) - pipe, err = connectTunnelServicePipe(tunnelName) - if err != nil { - return nil, err - } - pipe.SetDeadline(time.Now().Add(time.Second * 2)) - _, err = pipe.Write([]byte("get=1\n\n")) - } - if err != nil { - pipe.Unlock() - disconnectTunnelServicePipe(tunnelName) - return nil, err - } - conf, err := conf.FromUAPI(pipe, storedConfig) - pipe.Unlock() - if err != nil { - return nil, err - } - if s.elevatedToken == 0 { - conf.Redact() - } - return conf, nil + releaseDriverAdapter(tunnelName) + return nil, err } + conf := conf.FromDriverConfiguration(runtimeConfig, storedConfig) + driverAdapter.Unlock() + if s.elevatedToken == 0 { + conf.Redact() + } + return conf, nil } func (s *ManagerService) Start(tunnelName string) error { diff --git a/manager/ipc_uapi.go b/manager/ipc_uapi.go deleted file mode 100644 index 85477125..00000000 --- a/manager/ipc_uapi.go +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved. - */ - -package manager - -import ( - "net" - "sync" - - "golang.org/x/sys/windows" - "golang.zx2c4.com/wireguard/ipc/winpipe" - - "golang.zx2c4.com/wireguard/windows/services" -) - -type connectedTunnel struct { - net.Conn - sync.Mutex -} - -var connectedTunnelServicePipes = make(map[string]*connectedTunnel) -var connectedTunnelServicePipesLock sync.RWMutex - -func connectTunnelServicePipe(tunnelName string) (*connectedTunnel, error) { - connectedTunnelServicePipesLock.RLock() - pipe, ok := connectedTunnelServicePipes[tunnelName] - if ok { - pipe.Lock() - connectedTunnelServicePipesLock.RUnlock() - return pipe, nil - } - connectedTunnelServicePipesLock.RUnlock() - connectedTunnelServicePipesLock.Lock() - defer connectedTunnelServicePipesLock.Unlock() - pipe, ok = connectedTunnelServicePipes[tunnelName] - if ok { - pipe.Lock() - return pipe, nil - } - pipePath, err := services.PipePathOfTunnel(tunnelName) - if err != nil { - return nil, err - } - localSystem, err := windows.CreateWellKnownSid(windows.WinLocalSystemSid) - if err != nil { - return nil, err - } - pipe = &connectedTunnel{} - pipe.Conn, err = winpipe.Dial(pipePath, nil, &winpipe.DialConfig{ExpectedOwner: localSystem}) - if err != nil { - return nil, err - } - connectedTunnelServicePipes[tunnelName] = pipe - pipe.Lock() - return pipe, nil -} - -func disconnectTunnelServicePipe(tunnelName string) { - connectedTunnelServicePipesLock.Lock() - defer connectedTunnelServicePipesLock.Unlock() - pipe, ok := connectedTunnelServicePipes[tunnelName] - if !ok { - return - } - pipe.Lock() - pipe.Close() - delete(connectedTunnelServicePipes, tunnelName) - pipe.Unlock() -} diff --git a/manager/service.go b/manager/service.go index e5dcf92d..af9004de 100644 --- a/manager/service.go +++ b/manager/service.go @@ -17,7 +17,6 @@ import ( "golang.org/x/sys/windows" "golang.org/x/sys/windows/svc" - "golang.zx2c4.com/wireguard/tun/wintun" "golang.zx2c4.com/wireguard/windows/conf" "golang.zx2c4.com/wireguard/windows/elevate" @@ -259,11 +258,6 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest }() } - time.AfterFunc(time.Second*15, func() { - if !conf.AdminBool("UseUserspaceImplementation") { - wintun.Uninstall() - } - }) go checkForUpdates() var sessionsPointer *windows.WTS_SESSION_INFO diff --git a/manager/tunneltracker.go b/manager/tunneltracker.go index 6b5b1a02..103388f2 100644 --- a/manager/tunneltracker.go +++ b/manager/tunneltracker.go @@ -260,7 +260,6 @@ func trackTunnelService(tunnelName string, service *mgr.Service) { IPCServerNotifyTunnelChange(tunnelName, TunnelStopped, fmt.Errorf("Unable to continue monitoring service, so stopping: %w", err)) service.Control(svc.Stop) } - disconnectTunnelServicePipe(tunnelName) } func trackExistingTunnels() error { diff --git a/resources.rc b/resources.rc index aa4bb07d..1a8076fd 100644 --- a/resources.rc +++ b/resources.rc @@ -14,7 +14,6 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST manifest.xml 7 ICON ui/icon/wireguard.ico 8 ICON ui/icon/dot.ico -wintun.dll RCDATA wintun.dll wireguard.dll RCDATA wireguard.dll #define VERSIONINFO_TEMPLATE(block_id, lang_id, codepage_id, file_desc, comments) \ diff --git a/services/errors.go b/services/errors.go index e4fcc77d..763690e9 100644 --- a/services/errors.go +++ b/services/errors.go @@ -18,7 +18,6 @@ const ( ErrorRingloggerOpen ErrorLoadConfiguration ErrorCreateNetworkAdapter - ErrorUAPIListen ErrorDNSLookup ErrorFirewall ErrorDeviceSetConfig @@ -46,8 +45,6 @@ func (e Error) Error() string { return "Unable to load configuration from path" case ErrorCreateNetworkAdapter: return "Unable to create network adapter" - case ErrorUAPIListen: - return "Unable to listen on named pipe" case ErrorDNSLookup: return "Unable to resolve one or more DNS hostname endpoints" case ErrorFirewall: diff --git a/tunnel/addressconfig.go b/tunnel/addressconfig.go index c887f7b7..907cc546 100644 --- a/tunnel/addressconfig.go +++ b/tunnel/addressconfig.go @@ -76,7 +76,7 @@ func isDnsCacheDisabled() (bool, string) { return cfg.StartType == mgr.StartDisabled, cfg.DisplayName } -func configureInterface(family winipcfg.AddressFamily, conf *conf.Config, luid winipcfg.LUID, clamper mtuClamper) error { +func configureInterface(family winipcfg.AddressFamily, conf *conf.Config, luid winipcfg.LUID) error { estimatedRouteCount := 0 for _, peer := range conf.Peers { estimatedRouteCount += len(peer.AllowedIPs) @@ -172,9 +172,6 @@ func configureInterface(family winipcfg.AddressFamily, conf *conf.Config, luid w ipif.OtherStatefulConfigurationSupported = false if conf.Interface.MTU > 0 { ipif.NLMTU = uint32(conf.Interface.MTU) - if clamper != nil { - clamper.ForceMTU(int(ipif.NLMTU)) - } } if (family == windows.AF_INET && foundDefault4) || (family == windows.AF_INET6 && foundDefault6) { ipif.UseAutomaticMetric = false diff --git a/tunnel/defaultroutemonitor.go b/tunnel/defaultroutemonitor.go deleted file mode 100644 index 2a107fda..00000000 --- a/tunnel/defaultroutemonitor.go +++ /dev/null @@ -1,159 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved. - */ - -package tunnel - -import ( - "log" - "sync" - "time" - - "golang.org/x/sys/windows" - "golang.zx2c4.com/wireguard/conn" - "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" -) - -func bindSocketRoute(family winipcfg.AddressFamily, binder conn.BindSocketToInterface, ourLUID winipcfg.LUID, lastLUID *winipcfg.LUID, lastIndex *uint32, blackholeWhenLoop bool) error { - r, err := winipcfg.GetIPForwardTable2(family) - if err != nil { - return err - } - lowestMetric := ^uint32(0) - index := uint32(0) // Zero is "unspecified", which for IP_UNICAST_IF resets the value, which is what we want. - luid := winipcfg.LUID(0) // Hopefully luid zero is unspecified, but hard to find docs saying so. - for i := range r { - if r[i].DestinationPrefix.PrefixLength != 0 || r[i].InterfaceLUID == ourLUID { - continue - } - ifrow, err := r[i].InterfaceLUID.Interface() - if err != nil || ifrow.OperStatus != winipcfg.IfOperStatusUp { - continue - } - - iface, err := r[i].InterfaceLUID.IPInterface(family) - if err != nil { - continue - } - - if r[i].Metric+iface.Metric < lowestMetric { - lowestMetric = r[i].Metric + iface.Metric - index = r[i].InterfaceIndex - luid = r[i].InterfaceLUID - } - } - if luid == *lastLUID && index == *lastIndex { - return nil - } - *lastLUID = luid - *lastIndex = index - blackhole := blackholeWhenLoop && index == 0 - if family == windows.AF_INET { - log.Printf("Binding v4 socket to interface %d (blackhole=%v)", index, blackhole) - return binder.BindSocketToInterface4(index, blackhole) - } else if family == windows.AF_INET6 { - log.Printf("Binding v6 socket to interface %d (blackhole=%v)", index, blackhole) - return binder.BindSocketToInterface6(index, blackhole) - } - return nil -} - -type mtuClamper interface { - ForceMTU(mtu int) -} - -func monitorDefaultRoutes(family winipcfg.AddressFamily, binder conn.BindSocketToInterface, autoMTU bool, blackholeWhenLoop bool, clamper mtuClamper, ourLUID winipcfg.LUID) ([]winipcfg.ChangeCallback, error) { - var minMTU uint32 - if family == windows.AF_INET { - minMTU = 576 - } else if family == windows.AF_INET6 { - minMTU = 1280 - } - lastLUID := winipcfg.LUID(0) - lastIndex := ^uint32(0) - lastMTU := uint32(0) - doIt := func() error { - err := bindSocketRoute(family, binder, ourLUID, &lastLUID, &lastIndex, blackholeWhenLoop) - if err != nil { - return err - } - if !autoMTU { - return nil - } - mtu := uint32(0) - if lastLUID != 0 { - iface, err := lastLUID.Interface() - if err != nil { - return err - } - if iface.MTU > 0 { - mtu = iface.MTU - } - } - if mtu > 0 && lastMTU != mtu { - iface, err := ourLUID.IPInterface(family) - if err != nil { - return err - } - iface.NLMTU = mtu - 80 - if iface.NLMTU < minMTU { - iface.NLMTU = minMTU - } - err = iface.Set() - if err != nil { - return err - } - - // Having one MTU for both v4 and v6 kind of breaks the Windows model, unfortunately. - clamper.ForceMTU(int(iface.NLMTU)) - lastMTU = mtu - } - return nil - } - err := doIt() - if err != nil { - return nil, err - } - - firstBurst := time.Time{} - burstMutex := sync.Mutex{} - burstTimer := time.AfterFunc(time.Hour*200, func() { - burstMutex.Lock() - firstBurst = time.Time{} - doIt() - burstMutex.Unlock() - }) - burstTimer.Stop() - bump := func() { - burstMutex.Lock() - burstTimer.Reset(time.Millisecond * 150) - if firstBurst.IsZero() { - firstBurst = time.Now() - } else if time.Since(firstBurst) > time.Second*2 { - firstBurst = time.Time{} - burstTimer.Stop() - doIt() - } - burstMutex.Unlock() - } - - cbr, err := winipcfg.RegisterRouteChangeCallback(func(notificationType winipcfg.MibNotificationType, route *winipcfg.MibIPforwardRow2) { - if route != nil && route.DestinationPrefix.PrefixLength == 0 { - bump() - } - }) - if err != nil { - return nil, err - } - cbi, err := winipcfg.RegisterInterfaceChangeCallback(func(notificationType winipcfg.MibNotificationType, iface *winipcfg.MibIPInterfaceRow) { - if notificationType == winipcfg.MibParameterNotification { - bump() - } - }) - if err != nil { - cbr.Unregister() - return nil, err - } - return []winipcfg.ChangeCallback{cbr, cbi}, nil -} diff --git a/tunnel/interfacewatcher.go b/tunnel/interfacewatcher.go index 4e28a6a2..5ca2c69d 100644 --- a/tunnel/interfacewatcher.go +++ b/tunnel/interfacewatcher.go @@ -11,10 +11,8 @@ import ( "sync" "golang.org/x/sys/windows" - "golang.zx2c4.com/wireguard/windows/driver" - - "golang.zx2c4.com/wireguard/conn" "golang.zx2c4.com/wireguard/windows/conf" + "golang.zx2c4.com/wireguard/windows/driver" "golang.zx2c4.com/wireguard/windows/services" "golang.zx2c4.com/wireguard/windows/tunnel/firewall" "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" @@ -31,8 +29,6 @@ type interfaceWatcherEvent struct { type interfaceWatcher struct { errors chan interfaceWatcherError - binder conn.BindSocketToInterface - clamper mtuClamper conf *conf.Config adapter *driver.Adapter luid winipcfg.LUID @@ -44,44 +40,6 @@ type interfaceWatcher struct { storedEvents []interfaceWatcherEvent } -func hasDefaultRoute(family winipcfg.AddressFamily, peers []conf.Peer) bool { - var ( - foundV401 bool - foundV41281 bool - foundV600001 bool - foundV680001 bool - foundV400 bool - foundV600 bool - v40 = [4]byte{} - v60 = [16]byte{} - v48 = [4]byte{0x80} - v68 = [16]byte{0x80} - ) - for _, peer := range peers { - for _, allowedip := range peer.AllowedIPs { - if allowedip.Cidr == 1 && len(allowedip.IP) == 16 && allowedip.IP.Equal(v60[:]) { - foundV600001 = true - } else if allowedip.Cidr == 1 && len(allowedip.IP) == 16 && allowedip.IP.Equal(v68[:]) { - foundV680001 = true - } else if allowedip.Cidr == 1 && len(allowedip.IP) == 4 && allowedip.IP.Equal(v40[:]) { - foundV401 = true - } else if allowedip.Cidr == 1 && len(allowedip.IP) == 4 && allowedip.IP.Equal(v48[:]) { - foundV41281 = true - } else if allowedip.Cidr == 0 && len(allowedip.IP) == 16 && allowedip.IP.Equal(v60[:]) { - foundV600 = true - } else if allowedip.Cidr == 0 && len(allowedip.IP) == 4 && allowedip.IP.Equal(v40[:]) { - foundV400 = true - } - } - } - if family == windows.AF_INET { - return foundV400 || (foundV401 && foundV41281) - } else if family == windows.AF_INET6 { - return foundV600 || (foundV600001 && foundV680001) - } - return false -} - func (iw *interfaceWatcher) setup(family winipcfg.AddressFamily) { var changeCallbacks *[]winipcfg.ChangeCallback var ipversion string @@ -102,14 +60,7 @@ func (iw *interfaceWatcher) setup(family winipcfg.AddressFamily) { } var err error - if iw.binder != nil && iw.clamper != nil { - log.Printf("Monitoring default %s routes", ipversion) - *changeCallbacks, err = monitorDefaultRoutes(family, iw.binder, iw.conf.Interface.MTU == 0, hasDefaultRoute(family, iw.conf.Peers), iw.clamper, iw.luid) - if err != nil { - iw.errors <- interfaceWatcherError{services.ErrorBindSocketsToDefaultRoutes, err} - return - } - } else if iw.conf.Interface.MTU == 0 { + if iw.conf.Interface.MTU == 0 { log.Printf("Monitoring MTU of default %s routes", ipversion) *changeCallbacks, err = monitorMTU(family, iw.luid) if err != nil { @@ -119,7 +70,7 @@ func (iw *interfaceWatcher) setup(family winipcfg.AddressFamily) { } log.Printf("Setting device %s addresses", ipversion) - err = configureInterface(family, iw.conf, iw.luid, iw.clamper) + err = configureInterface(family, iw.conf, iw.luid) if err != nil { iw.errors <- interfaceWatcherError{services.ErrorSetNetConfig, err} return @@ -147,17 +98,15 @@ func watchInterface() (*interfaceWatcher, error) { } iw.setup(iface.Family) - if iw.adapter != nil { - if state, err := iw.adapter.AdapterState(); err == nil && state == driver.AdapterStateDown { - log.Println("Reinitializing adapter configuration") - err = iw.adapter.SetConfiguration(iw.conf.ToDriverConfiguration()) - if err != nil { - log.Println(fmt.Errorf("%v: %w", services.ErrorDeviceSetConfig, err)) - } - err = iw.adapter.SetAdapterState(driver.AdapterStateUp) - if err != nil { - log.Println(fmt.Errorf("%v: %w", services.ErrorDeviceBringUp, err)) - } + if state, err := iw.adapter.AdapterState(); err == nil && state == driver.AdapterStateDown { + log.Println("Reinitializing adapter configuration") + err = iw.adapter.SetConfiguration(iw.conf.ToDriverConfiguration()) + if err != nil { + log.Println(fmt.Errorf("%v: %w", services.ErrorDeviceSetConfig, err)) + } + err = iw.adapter.SetAdapterState(driver.AdapterStateUp) + if err != nil { + log.Println(fmt.Errorf("%v: %w", services.ErrorDeviceBringUp, err)) } } }) @@ -167,11 +116,11 @@ func watchInterface() (*interfaceWatcher, error) { return iw, nil } -func (iw *interfaceWatcher) Configure(binder conn.BindSocketToInterface, clamper mtuClamper, adapter *driver.Adapter, conf *conf.Config, luid winipcfg.LUID) { +func (iw *interfaceWatcher) Configure(adapter *driver.Adapter, conf *conf.Config, luid winipcfg.LUID) { iw.setupMutex.Lock() defer iw.setupMutex.Unlock() - iw.binder, iw.clamper, iw.adapter, iw.conf, iw.luid = binder, clamper, adapter, conf, luid + iw.adapter, iw.conf, iw.luid = adapter, conf, luid for _, event := range iw.storedEvents { if event.luid == luid { iw.setup(event.family) diff --git a/tunnel/ipcpermissions.go b/tunnel/ipcpermissions.go deleted file mode 100644 index 3a676e4b..00000000 --- a/tunnel/ipcpermissions.go +++ /dev/null @@ -1,63 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved. - */ - -package tunnel - -import ( - "golang.org/x/sys/windows" - - "golang.zx2c4.com/wireguard/ipc" - - "golang.zx2c4.com/wireguard/windows/conf" -) - -func CopyConfigOwnerToIPCSecurityDescriptor(filename string) error { - if conf.PathIsEncrypted(filename) { - return nil - } - - fileSd, err := windows.GetNamedSecurityInfo(filename, windows.SE_FILE_OBJECT, windows.OWNER_SECURITY_INFORMATION) - if err != nil { - return err - } - fileOwner, _, err := fileSd.Owner() - if err != nil { - return err - } - if fileOwner.IsWellKnown(windows.WinLocalSystemSid) { - return nil - } - additionalEntries := []windows.EXPLICIT_ACCESS{{ - AccessPermissions: windows.GENERIC_ALL, - AccessMode: windows.GRANT_ACCESS, - Trustee: windows.TRUSTEE{ - TrusteeForm: windows.TRUSTEE_IS_SID, - TrusteeType: windows.TRUSTEE_IS_USER, - TrusteeValue: windows.TrusteeValueFromSID(fileOwner), - }, - }} - - sd, err := ipc.UAPISecurityDescriptor.ToAbsolute() - if err != nil { - return err - } - dacl, defaulted, _ := sd.DACL() - - newDacl, err := windows.ACLFromEntries(additionalEntries, dacl) - if err != nil { - return err - } - err = sd.SetDACL(newDacl, true, defaulted) - if err != nil { - return err - } - sd, err = sd.ToSelfRelative() - if err != nil { - return err - } - ipc.UAPISecurityDescriptor = sd - - return nil -} diff --git a/tunnel/service.go b/tunnel/service.go index 57d0ef91..013548df 100644 --- a/tunnel/service.go +++ b/tunnel/service.go @@ -9,7 +9,6 @@ import ( "bytes" "fmt" "log" - "net" "os" "runtime" "time" @@ -17,10 +16,7 @@ import ( "golang.org/x/sys/windows" "golang.org/x/sys/windows/svc" "golang.org/x/sys/windows/svc/mgr" - "golang.zx2c4.com/wireguard/conn" - "golang.zx2c4.com/wireguard/device" - "golang.zx2c4.com/wireguard/ipc" - "golang.zx2c4.com/wireguard/tun" + "golang.zx2c4.com/wireguard/windows/conf" "golang.zx2c4.com/wireguard/windows/driver" "golang.zx2c4.com/wireguard/windows/elevate" @@ -37,11 +33,7 @@ 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} - var dev *device.Device - var uapi net.Listener var watcher *interfaceWatcher - var nativeTun *tun.NativeTun - var wintun tun.Device var adapter *driver.Adapter var luid winipcfg.LUID var config *conf.Config @@ -88,22 +80,16 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest, } }() - if logErr == nil && (dev != nil || adapter != nil) && config != nil { + if logErr == nil && adapter != nil && config != nil { logErr = runScriptCommand(config.Interface.PreDown, config.Name) } if watcher != nil { watcher.Destroy() } - if uapi != nil { - uapi.Close() - } - if dev != nil { - dev.Close() - } if adapter != nil { adapter.Close() } - if logErr == nil && (dev != nil || adapter != nil) && config != nil { + if logErr == nil && adapter != nil && config != nil { _ = runScriptCommand(config.Interface.PostDown, config.Name) } stopIt <- true @@ -128,11 +114,6 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest, return } config.DeduplicateNetworkEntries() - err = CopyConfigOwnerToIPCSecurityDescriptor(service.Path) - if err != nil { - serviceError = services.ErrorLoadConfiguration - return - } log.SetPrefix(fmt.Sprintf("[%s] ", config.Name)) @@ -166,58 +147,33 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest, } log.Println("Creating network adapter") - if UseFixedGUIDInsteadOfDeterministic || !conf.AdminBool("UseUserspaceImplementation") { - for i := 0; i < 5; i++ { - if i > 0 { - time.Sleep(time.Second) - log.Printf("Retrying adapter creation after failure because system just booted (T+%v): %v", windows.DurationSinceBoot(), err) - } - adapter, err = driver.CreateAdapter(config.Name, "WireGuard", deterministicGUID(config)) - if err == nil || windows.DurationSinceBoot() > time.Minute*10 { - break - } - } - if err != nil { - err = fmt.Errorf("Error creating adapter: %w", err) - serviceError = services.ErrorCreateNetworkAdapter - return + for i := 0; i < 5; i++ { + if i > 0 { + time.Sleep(time.Second) + log.Printf("Retrying adapter creation after failure because system just booted (T+%v): %v", windows.DurationSinceBoot(), err) } - luid = adapter.LUID() - driverVersion, err := driver.RunningVersion() - if err != nil { - log.Printf("Warning: unable to determine driver version: %v", err) - } else { - log.Printf("Using WireGuardNT/%d.%d", (driverVersion>>16)&0xffff, driverVersion&0xffff) - } - err = adapter.SetLogging(driver.AdapterLogOn) - if err != nil { - err = fmt.Errorf("Error enabling adapter logging: %w", err) - serviceError = services.ErrorCreateNetworkAdapter - return + adapter, err = driver.CreateAdapter(config.Name, "WireGuard", deterministicGUID(config)) + if err == nil || windows.DurationSinceBoot() > time.Minute*10 { + break } + } + if err != nil { + err = fmt.Errorf("Error creating adapter: %w", err) + serviceError = services.ErrorCreateNetworkAdapter + return + } + luid = adapter.LUID() + driverVersion, err := driver.RunningVersion() + if err != nil { + log.Printf("Warning: unable to determine driver version: %v", err) } else { - for i := 0; i < 5; i++ { - if i > 0 { - time.Sleep(time.Second) - log.Printf("Retrying adapter creation after failure because system just booted (T+%v): %v", windows.DurationSinceBoot(), err) - } - wintun, err = tun.CreateTUNWithRequestedGUID(config.Name, deterministicGUID(config), 0) - if err == nil || windows.DurationSinceBoot() > time.Minute*10 { - break - } - } - if err != nil { - serviceError = services.ErrorCreateNetworkAdapter - return - } - nativeTun = wintun.(*tun.NativeTun) - luid = winipcfg.LUID(nativeTun.LUID()) - driverVersion, err := nativeTun.RunningVersion() - if err != nil { - log.Printf("Warning: unable to determine driver version: %v", err) - } else { - log.Printf("Using Wintun/%d.%d", (driverVersion>>16)&0xffff, driverVersion&0xffff) - } + log.Printf("Using WireGuardNT/%d.%d", (driverVersion>>16)&0xffff, driverVersion&0xffff) + } + err = adapter.SetLogging(driver.AdapterLogOn) + if err != nil { + err = fmt.Errorf("Error enabling adapter logging: %w", err) + serviceError = services.ErrorCreateNetworkAdapter + return } err = runScriptCommand(config.Interface.PreUp, config.Name) @@ -239,54 +195,18 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest, return } - if nativeTun != nil { - log.Println("Creating interface instance") - bind := conn.NewDefaultBind() - dev = device.NewDevice(wintun, bind, &device.Logger{log.Printf, log.Printf}) - - log.Println("Setting interface configuration") - uapi, err = ipc.UAPIListen(config.Name) - if err != nil { - serviceError = services.ErrorUAPIListen - return - } - err = dev.IpcSet(config.ToUAPI()) - if err != nil { - serviceError = services.ErrorDeviceSetConfig - return - } - - log.Println("Bringing peers up") - dev.Up() - - var clamper mtuClamper - clamper = nativeTun - watcher.Configure(bind.(conn.BindSocketToInterface), clamper, nil, config, luid) - - log.Println("Listening for UAPI requests") - go func() { - for { - conn, err := uapi.Accept() - if err != nil { - continue - } - go dev.IpcHandle(conn) - } - }() - } else { - log.Println("Setting interface configuration") - err = adapter.SetConfiguration(config.ToDriverConfiguration()) - if err != nil { - serviceError = services.ErrorDeviceSetConfig - return - } - err = adapter.SetAdapterState(driver.AdapterStateUp) - if err != nil { - serviceError = services.ErrorDeviceBringUp - return - } - watcher.Configure(nil, nil, adapter, config, luid) + log.Println("Setting interface configuration") + err = adapter.SetConfiguration(config.ToDriverConfiguration()) + if err != nil { + serviceError = services.ErrorDeviceSetConfig + return } + err = adapter.SetAdapterState(driver.AdapterStateUp) + if err != nil { + serviceError = services.ErrorDeviceBringUp + return + } + watcher.Configure(adapter, config, luid) err = runScriptCommand(config.Interface.PostUp, config.Name) if err != nil { @@ -297,12 +217,6 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest, changes <- svc.Status{State: svc.Running, Accepts: svc.AcceptStop | svc.AcceptShutdown} log.Println("Startup complete") - var devWaitChan chan struct{} - if dev != nil { - devWaitChan = dev.Wait() - } else { - devWaitChan = make(chan struct{}) - } for { select { case c := <-r: @@ -314,8 +228,6 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest, default: log.Printf("Unexpected service control request #%d\n", c) } - case <-devWaitChan: - return case e := <-watcher.errors: serviceError, err = e.serviceError, e.err return diff --git a/tunnel/winipcfg/winipcfg_test.go b/tunnel/winipcfg/winipcfg_test.go index 7689a0c1..5d3bc276 100644 --- a/tunnel/winipcfg/winipcfg_test.go +++ b/tunnel/winipcfg/winipcfg_test.go @@ -8,8 +8,8 @@ Some tests in this file require: - A dedicated network adapter - Any network adapter will do. It may be virtual (Wintun etc.). The adapter name - must contain string "winipcfg_test". + Any network adapter will do. It may be virtual (WireGuardNT, Wintun, + etc.). The adapter name must contain string "winipcfg_test". Tests will add, remove, flush DNS servers, change adapter IP address, manipulate routes etc. The adapter will not be returned to previous state, so use an expendable one. diff --git a/tunnel/wintun_test.go b/tunnel/wintun_test.go deleted file mode 100644 index 4e56ff65..00000000 --- a/tunnel/wintun_test.go +++ /dev/null @@ -1,202 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved. - */ - -package tunnel_test - -import ( - "bytes" - "crypto/rand" - "encoding/binary" - "fmt" - "net" - "sync" - "testing" - "time" - - "golang.org/x/sys/windows" - - "golang.zx2c4.com/wireguard/tun" - - "golang.zx2c4.com/wireguard/windows/elevate" - "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" -) - -func TestWintunOrdering(t *testing.T) { - var tunDevice tun.Device - err := elevate.DoAsSystem(func() error { - var err error - tunDevice, err = tun.CreateTUNWithRequestedGUID("tunordertest", &windows.GUID{12, 12, 12, [8]byte{12, 12, 12, 12, 12, 12, 12, 12}}, 1500) - return err - }) - if err != nil { - t.Fatal(err) - } - defer tunDevice.Close() - nativeTunDevice := tunDevice.(*tun.NativeTun) - luid := winipcfg.LUID(nativeTunDevice.LUID()) - ip, ipnet, _ := net.ParseCIDR("10.82.31.4/24") - err = luid.SetIPAddresses([]net.IPNet{{ip, ipnet.Mask}}) - if err != nil { - t.Fatal(err) - } - err = luid.SetRoutes([]*winipcfg.RouteData{{*ipnet, ipnet.IP, 0}}) - if err != nil { - t.Fatal(err) - } - var token [32]byte - _, err = rand.Read(token[:]) - if err != nil { - t.Fatal(err) - } - var sockWrite net.Conn - for i := 0; i < 1000; i++ { - sockWrite, err = net.Dial("udp", "10.82.31.5:9999") - if err == nil { - defer sockWrite.Close() - break - } - time.Sleep(time.Millisecond * 100) - } - if err != nil { - t.Fatal(err) - } - var sockRead *net.UDPConn - for i := 0; i < 1000; i++ { - var listenAddress *net.UDPAddr - listenAddress, err = net.ResolveUDPAddr("udp", "10.82.31.4:9999") - if err != nil { - continue - } - sockRead, err = net.ListenUDP("udp", listenAddress) - if err == nil { - defer sockRead.Close() - break - } - time.Sleep(time.Millisecond * 100) - } - if err != nil { - t.Fatal(err) - } - var wait sync.WaitGroup - wait.Add(4) - doneSockWrite := false - doneTunWrite := false - fatalErrors := make(chan error, 2) - errors := make(chan error, 2) - go func() { - defer wait.Done() - buffer := append(token[:], 0, 0, 0, 0, 0, 0, 0, 0) - for sendingIndex := uint64(0); !doneSockWrite; sendingIndex++ { - binary.LittleEndian.PutUint64(buffer[32:], sendingIndex) - _, err := sockWrite.Write(buffer[:]) - if err != nil { - fatalErrors <- err - } - } - }() - go func() { - defer wait.Done() - packet := [20 + 8 + 32 + 8]byte{ - 0x45, 0, 0, 20 + 8 + 32 + 8, - 0, 0, 0, 0, - 0x80, 0x11, 0, 0, - 10, 82, 31, 5, - 10, 82, 31, 4, - 8888 >> 8, 8888 & 0xff, 9999 >> 8, 9999 & 0xff, 0, 8 + 32 + 8, 0, 0, - } - copy(packet[28:], token[:]) - for sendingIndex := uint64(0); !doneTunWrite; sendingIndex++ { - binary.BigEndian.PutUint16(packet[4:], uint16(sendingIndex)) - var checksum uint32 - for i := 0; i < 20; i += 2 { - if i != 10 { - checksum += uint32(binary.BigEndian.Uint16(packet[i:])) - } - } - binary.BigEndian.PutUint16(packet[10:], ^(uint16(checksum>>16) + uint16(checksum&0xffff))) - binary.LittleEndian.PutUint64(packet[20+8+32:], sendingIndex) - n, err := tunDevice.Write(packet[:], 0) - if err != nil { - fatalErrors <- err - } - if n == 0 { - time.Sleep(time.Millisecond * 300) - } - } - }() - const packetsPerTest = 1 << 21 - go func() { - defer func() { - doneSockWrite = true - wait.Done() - }() - var expectedIndex uint64 - for i := uint64(0); i < packetsPerTest; { - var buffer [(1 << 16) - 1]byte - bytesRead, err := tunDevice.Read(buffer[:], 0) - if err != nil { - fatalErrors <- err - } - if bytesRead < 0 || bytesRead > len(buffer) { - continue - } - packet := buffer[:bytesRead] - tokenPos := bytes.Index(packet, token[:]) - if tokenPos == -1 || tokenPos+32+8 > len(packet) { - continue - } - foundIndex := binary.LittleEndian.Uint64(packet[tokenPos+32:]) - if foundIndex < expectedIndex { - errors <- fmt.Errorf("Sock write, tun read: expected packet %d, received packet %d", expectedIndex, foundIndex) - } - expectedIndex = foundIndex + 1 - i++ - } - }() - go func() { - defer func() { - doneTunWrite = true - wait.Done() - }() - var expectedIndex uint64 - for i := uint64(0); i < packetsPerTest; { - var buffer [(1 << 16) - 1]byte - bytesRead, err := sockRead.Read(buffer[:]) - if err != nil { - fatalErrors <- err - } - if bytesRead < 0 || bytesRead > len(buffer) { - continue - } - packet := buffer[:bytesRead] - if len(packet) != 32+8 || !bytes.HasPrefix(packet, token[:]) { - continue - } - foundIndex := binary.LittleEndian.Uint64(packet[32:]) - if foundIndex < expectedIndex { - errors <- fmt.Errorf("Tun write, sock read: expected packet %d, received packet %d", expectedIndex, foundIndex) - } - expectedIndex = foundIndex + 1 - i++ - } - }() - done := make(chan bool, 2) - doneFunc := func() { - wait.Wait() - done <- true - } - defer doneFunc() - go doneFunc() - for { - select { - case err := <-fatalErrors: - t.Fatal(err) - case err := <-errors: - t.Error(err) - case <-done: - return - } - } -} |