Skip to content

Commit e93f338

Browse files
committed
internal/windows: cache interface rather than instance ID
Apparently instance ID is not stable between S3 sleep on recent Windows builds. Reported-by: J. Michael McAtee <[email protected]> Reported-by: Menno Finlay-Smits <[email protected]> Signed-off-by: Jason A. Donenfeld <[email protected]>
1 parent 3d4a969 commit e93f338

File tree

1 file changed

+35
-27
lines changed

1 file changed

+35
-27
lines changed

internal/wgwindows/client_windows.go

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ var _ wginternal.Client = &Client{}
1717

1818
// A Client provides access to WireGuardNT ioctl information.
1919
type Client struct {
20-
cachedAdapters map[string]string
21-
lastLenGuess uint32
20+
cachedInterfaces map[string]*uint16
21+
lastLenGuess uint32
2222
}
2323

2424
var (
@@ -38,8 +38,8 @@ func init() {
3838
}
3939
}
4040

41-
func (c *Client) refreshInstanceIdCache() error {
42-
cachedAdapters := make(map[string]string, 5)
41+
func (c *Client) refreshInterfaceCache() error {
42+
cachedInterfaces := make(map[string]*uint16, 5)
4343
devInfo, err := windows.SetupDiGetClassDevsEx(&deviceClassNetGUID, enumerator, 0, windows.DIGCF_PRESENT, 0, "")
4444
if err != nil {
4545
return err
@@ -70,43 +70,51 @@ func (c *Client) refreshInstanceIdCache() error {
7070
if err != nil {
7171
continue
7272
}
73-
cachedAdapters[adapterName] = instanceId
73+
interfaces, err := windows.CM_Get_Device_Interface_List(instanceId, &deviceInterfaceNetGUID, windows.CM_GET_DEVICE_INTERFACE_LIST_PRESENT)
74+
if err != nil {
75+
continue
76+
}
77+
interface16, err := windows.UTF16PtrFromString(interfaces[0])
78+
if err != nil {
79+
continue
80+
}
81+
cachedInterfaces[adapterName] = interface16
7482
}
75-
c.cachedAdapters = cachedAdapters
83+
c.cachedInterfaces = cachedInterfaces
7684
return nil
7785
}
7886

79-
func (c *Client) interfaceHandle(name string) (windows.Handle, error) {
80-
instanceId, ok := c.cachedAdapters[name]
81-
if !ok {
82-
err := c.refreshInstanceIdCache()
83-
if err != nil {
84-
return 0, err
85-
}
86-
instanceId, ok = c.cachedAdapters[name]
87+
func (c *Client) interfaceHandle(name string) (handle windows.Handle, err error) {
88+
hasRefreshed := false
89+
for !hasRefreshed {
90+
fileName, ok := c.cachedInterfaces[name]
8791
if !ok {
88-
return 0, os.ErrNotExist
92+
err := c.refreshInterfaceCache()
93+
if err != nil {
94+
return 0, err
95+
}
96+
hasRefreshed = true
97+
fileName, ok = c.cachedInterfaces[name]
98+
if !ok {
99+
return 0, os.ErrNotExist
100+
}
101+
}
102+
handle, err = windows.CreateFile(fileName, windows.GENERIC_READ|windows.GENERIC_WRITE, windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE|windows.FILE_SHARE_DELETE, nil, windows.OPEN_EXISTING, 0, 0)
103+
if err == nil {
104+
break
89105
}
90106
}
91-
interfaces, err := windows.CM_Get_Device_Interface_List(instanceId, &deviceInterfaceNetGUID, windows.CM_GET_DEVICE_INTERFACE_LIST_PRESENT)
92-
if err != nil {
93-
return 0, err
94-
}
95-
interface16, err := windows.UTF16PtrFromString(interfaces[0])
96-
if err != nil {
97-
return 0, err
98-
}
99-
return windows.CreateFile(interface16, windows.GENERIC_READ|windows.GENERIC_WRITE, windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE|windows.FILE_SHARE_DELETE, nil, windows.OPEN_EXISTING, 0, 0)
107+
return
100108
}
101109

102110
// Devices implements wginternal.Client.
103111
func (c *Client) Devices() ([]*wgtypes.Device, error) {
104-
err := c.refreshInstanceIdCache()
112+
err := c.refreshInterfaceCache()
105113
if err != nil {
106114
return nil, err
107115
}
108-
ds := make([]*wgtypes.Device, 0, len(c.cachedAdapters))
109-
for name := range c.cachedAdapters {
116+
ds := make([]*wgtypes.Device, 0, len(c.cachedInterfaces))
117+
for name := range c.cachedInterfaces {
110118
d, err := c.Device(name)
111119
if err != nil {
112120
return nil, err

0 commit comments

Comments
 (0)