Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(vpn): fail early if wintun.dll is not present #16707

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 28, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 31 additions & 3 deletions vpn/tun_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ import (
"github.com/coder/retry"
)

const tunName = "Coder"
const (
tunName = "Coder"
tunGUID = "{0ed1515d-04a4-4c46-abae-11ad07cf0e6d}"

wintunDLL = "wintun.dll"
)

func GetNetworkingStack(t *Tunnel, _ *StartRequest, logger slog.Logger) (NetworkStack, error) {
// Initialize COM process-wide so Tailscale can make calls to the windows
Expand All @@ -44,12 +49,35 @@ func GetNetworkingStack(t *Tunnel, _ *StartRequest, logger slog.Logger) (Network

// Set the name and GUID for the TUN interface.
tun.WintunTunnelType = tunName
guid, err := windows.GUIDFromString("{0ed1515d-04a4-4c46-abae-11ad07cf0e6d}")
guid, err := windows.GUIDFromString(tunGUID)
if err != nil {
panic(err)
return NetworkStack{}, xerrors.Errorf("could not parse GUID %q: %w", tunGUID, err)
}
tun.WintunStaticRequestedGUID = &guid

// Ensure wintun.dll is available, and fail early if it's not to avoid
// hanging for 5 minutes in tstunNewWithWindowsRetries.
//
// First, we call wintun.Version() to make the wintun package attempt to
// load wintun.dll. This allows the wintun package to set the logging
// callback in the DLL before we load it ourselves.
_ = wintun.Version()

// Then, we try to load wintun.dll ourselves so we get a better error
// message if there was a problem. This call matches the wintun package, so
// we're loading it in the same way.
//
// Note: this leaks the handle to wintun.dll, but since it's already loaded
// it wouldn't be freed anyways.
const (
LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 0x00000200
LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
)
_, err = windows.LoadLibraryEx(wintunDLL, 0, LOAD_LIBRARY_SEARCH_APPLICATION_DIR|LOAD_LIBRARY_SEARCH_SYSTEM32)
if err != nil {
return NetworkStack{}, xerrors.Errorf("could not load %q, it should be in the same directory as the executable (in Coder Desktop, this should have been installed automatically): %w", wintunDLL, err)
}

tunDev, tunName, err := tstunNewWithWindowsRetries(tailnet.Logger(logger.Named("net.tun.device")), tunName)
if err != nil {
return NetworkStack{}, xerrors.Errorf("create tun device: %w", err)
Expand Down
Loading