Update wintun to be compatible with our AWG

This commit is contained in:
Mykola Baibuz
2023-10-09 22:36:04 +03:00
parent dd07f4a86e
commit a9476c337d
5 changed files with 4 additions and 228 deletions

View File

@@ -16,7 +16,7 @@ if exist .deps\prepared goto :build
call :download go.zip https://go.dev/dl/go1.20.8.windows-amd64.zip 6308336f7060023f2c9c58cdeefaa1389b5c4a96b4bd87b6ad742c57f8ac00da || goto :error
rem Mirror of https://github.com/mstorsjo/llvm-mingw/releases/download/20201020/llvm-mingw-20201020-msvcrt-x86_64.zip
call :download llvm-mingw-msvcrt.zip https://download.wireguard.com/windows-toolchain/distfiles/llvm-mingw-20201020-msvcrt-x86_64.zip 2e46593245090df96d15e360e092f0b62b97e93866e0162dca7f93b16722b844 || goto :error
call :download wintun.zip https://www.wintun.net/builds/wintun-0.12.zip eba90e26686ed86595ae0a6d4d3f4f022924b1758f5148a32a91c60cc6e604df || goto :error
call :download wintun.zip https://www.wintun.net/builds/wintun-0.14.1.zip 07c256185d6ee3652e09fa55c0b673e2624b565e02c4b9091c79ca7d2f24ef51 || goto :error
copy /y NUL prepared > NUL || goto :error
cd .. || goto :error

2
go.mod
View File

@@ -3,7 +3,7 @@ module github.com/amnezia-vpn/awg-windows
go 1.16
require (
github.com/amnezia-vpn/amnezia-wg v0.1.4
github.com/amnezia-vpn/amnezia-wg v0.1.5
golang.org/x/crypto v0.14.0
golang.org/x/sys v0.13.0
golang.org/x/text v0.13.0

4
go.sum
View File

@@ -51,8 +51,8 @@ github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/amnezia-vpn/amnezia-wg v0.1.4 h1:ylQr2cHi8jpDPQHBmdP2ppb8Ou1eB8uzBZ3RutyyKSM=
github.com/amnezia-vpn/amnezia-wg v0.1.4/go.mod h1:y3O3XsXzUXQYDwRNulQbnnAAhsjPYCnBjGmb2Daes64=
github.com/amnezia-vpn/amnezia-wg v0.1.5 h1:FlQuZ64vDOBDC3f7PA3pY53CnkiUWR7M/LTX/X3gT/8=
github.com/amnezia-vpn/amnezia-wg v0.1.5/go.mod h1:y3O3XsXzUXQYDwRNulQbnnAAhsjPYCnBjGmb2Daes64=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/bazelbuild/rules_go v0.30.0/go.mod h1:MC23Dc/wkXEyk3Wpq6lCqz0ZAYOZDw2DR5y3N1q2i7M=

View File

@@ -1,47 +0,0 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
*/
package services
import (
"errors"
"log"
"sync"
"time"
"github.com/amnezia-vpn/awg-windows/version"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/svc"
)
var (
startedAtBoot bool
startedAtBootOnce sync.Once
)
func StartedAtBoot() bool {
startedAtBootOnce.Do(func() {
if isService, err := svc.IsWindowsService(); err == nil && !isService {
return
}
if reason, err := svc.DynamicStartReason(); err == nil {
startedAtBoot = (reason&svc.StartReasonAuto) != 0 || (reason&svc.StartReasonDelayedAuto) != 0
} else if errors.Is(err, windows.ERROR_PROC_NOT_FOUND) {
// TODO: Below this line is Windows 7 compatibility code, which hopefully we can delete at some point.
startedAtBoot = windows.DurationSinceBoot() < time.Minute*10
} else {
log.Printf("Unable to determine service start reason: %v", err)
}
})
return startedAtBoot
}
func PrintStarting() {
boot := ""
if StartedAtBoot() {
boot = " at boot"
}
log.Printf("Starting%s %s", boot, version.UserAgent())
}

View File

@@ -1,177 +0,0 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
*/
package tunnel
import (
"log"
"net/netip"
"strings"
"unsafe"
"github.com/amnezia-vpn/awg-windows/conf"
"github.com/amnezia-vpn/awg-windows/tunnel/winipcfg"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/svc/mgr"
)
func evaluateStaticPitfalls() {
go func() {
pitfallDnsCacheDisabled()
pitfallVirtioNetworkDriver()
}()
}
func evaluateDynamicPitfalls(family winipcfg.AddressFamily, conf *conf.Config, luid winipcfg.LUID) {
go func() {
pitfallWeakHostSend(family, conf, luid)
}()
}
func pitfallDnsCacheDisabled() {
scm, err := mgr.Connect()
if err != nil {
return
}
defer scm.Disconnect()
svc := mgr.Service{Name: "dnscache"}
svc.Handle, err = windows.OpenService(scm.Handle, windows.StringToUTF16Ptr(svc.Name), windows.SERVICE_QUERY_CONFIG)
if err != nil {
return
}
defer svc.Close()
cfg, err := svc.Config()
if err != nil {
return
}
if cfg.StartType != mgr.StartDisabled {
return
}
log.Printf("Warning: the %q (dnscache) service is disabled; please re-enable it", cfg.DisplayName)
}
func pitfallVirtioNetworkDriver() {
var modules []windows.RTL_PROCESS_MODULE_INFORMATION
for bufferSize := uint32(128 * 1024); ; {
moduleBuffer := make([]byte, bufferSize)
err := windows.NtQuerySystemInformation(windows.SystemModuleInformation, unsafe.Pointer(&moduleBuffer[0]), bufferSize, &bufferSize)
switch err {
case windows.STATUS_INFO_LENGTH_MISMATCH:
continue
case nil:
break
default:
return
}
mods := (*windows.RTL_PROCESS_MODULES)(unsafe.Pointer(&moduleBuffer[0]))
modules = unsafe.Slice(&mods.Modules[0], mods.NumberOfModules)
break
}
for i := range modules {
if !strings.EqualFold(windows.ByteSliceToString(modules[i].FullPathName[modules[i].OffsetToFileName:]), "netkvm.sys") {
continue
}
driverPath := `\\?\GLOBALROOT` + windows.ByteSliceToString(modules[i].FullPathName[:])
var zero windows.Handle
infoSize, err := windows.GetFileVersionInfoSize(driverPath, &zero)
if err != nil {
return
}
versionInfo := make([]byte, infoSize)
err = windows.GetFileVersionInfo(driverPath, 0, infoSize, unsafe.Pointer(&versionInfo[0]))
if err != nil {
return
}
var fixedInfo *windows.VS_FIXEDFILEINFO
fixedInfoLen := uint32(unsafe.Sizeof(*fixedInfo))
err = windows.VerQueryValue(unsafe.Pointer(&versionInfo[0]), `\`, unsafe.Pointer(&fixedInfo), &fixedInfoLen)
if err != nil {
return
}
const minimumPlausibleVersion = 40 << 48
const minimumGoodVersion = (100 << 48) | (85 << 32) | (104 << 16) | (20800 << 0)
version := (uint64(fixedInfo.FileVersionMS) << 32) | uint64(fixedInfo.FileVersionLS)
if version >= minimumGoodVersion || version < minimumPlausibleVersion {
return
}
log.Println("Warning: the VirtIO network driver (NetKVM) is out of date and may cause known problems; please update to v100.85.104.20800 or later")
return
}
}
func pitfallWeakHostSend(family winipcfg.AddressFamily, conf *conf.Config, ourLUID winipcfg.LUID) {
routingTable, err := winipcfg.GetIPForwardTable2(family)
if err != nil {
return
}
type endpointRoute struct {
addr netip.Addr
name string
lowestMetric uint32
highestCIDR uint8
weakHostSend bool
finalIsOurs bool
}
endpoints := make([]endpointRoute, 0, len(conf.Peers))
for _, peer := range conf.Peers {
addr, err := netip.ParseAddr(peer.Endpoint.Host)
if err != nil || (addr.Is4() && family != windows.AF_INET) || (addr.Is6() && family != windows.AF_INET6) {
continue
}
endpoints = append(endpoints, endpointRoute{addr: addr, lowestMetric: ^uint32(0)})
}
for i := range routingTable {
var (
ifrow *winipcfg.MibIfRow2
ifacerow *winipcfg.MibIPInterfaceRow
metric uint32
)
for j := range endpoints {
r, e := &routingTable[i], &endpoints[j]
if r.DestinationPrefix.PrefixLength < e.highestCIDR {
continue
}
if !r.DestinationPrefix.Prefix().Contains(e.addr) {
continue
}
if ifrow == nil {
ifrow, err = r.InterfaceLUID.Interface()
if err != nil {
continue
}
}
if ifrow.OperStatus != winipcfg.IfOperStatusUp {
continue
}
if ifacerow == nil {
ifacerow, err = r.InterfaceLUID.IPInterface(family)
if err != nil {
continue
}
metric = r.Metric + ifacerow.Metric
}
if r.DestinationPrefix.PrefixLength == e.highestCIDR && metric > e.lowestMetric {
continue
}
e.lowestMetric = metric
e.highestCIDR = r.DestinationPrefix.PrefixLength
e.finalIsOurs = r.InterfaceLUID == ourLUID
if !e.finalIsOurs {
e.name = ifrow.Alias()
e.weakHostSend = ifacerow.ForwardingEnabled || ifacerow.WeakHostSend
}
}
}
problematicInterfaces := make(map[string]bool, len(endpoints))
for _, e := range endpoints {
if e.weakHostSend && e.finalIsOurs {
problematicInterfaces[e.name] = true
}
}
for iface := range problematicInterfaces {
log.Printf("Warning: the %q interface has Forwarding/WeakHostSend enabled, which will cause routing loops", iface)
}
}