Add windows support
This commit is contained in:
parent
4f7247190c
commit
6c2c28da9d
54 changed files with 7023 additions and 191 deletions
88
internal/winipcfg/route_change_handler.go
Normal file
88
internal/winipcfg/route_change_handler.go
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
||||
*/
|
||||
|
||||
package winipcfg
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// RouteChangeCallback structure allows route change callback handling.
|
||||
type RouteChangeCallback struct {
|
||||
cb func(notificationType MibNotificationType, route *MibIPforwardRow2)
|
||||
wait sync.WaitGroup
|
||||
}
|
||||
|
||||
var (
|
||||
routeChangeAddRemoveMutex = sync.Mutex{}
|
||||
routeChangeMutex = sync.Mutex{}
|
||||
routeChangeCallbacks = make(map[*RouteChangeCallback]bool)
|
||||
routeChangeHandle = windows.Handle(0)
|
||||
)
|
||||
|
||||
// RegisterRouteChangeCallback registers a new RouteChangeCallback. If this particular callback is already
|
||||
// registered, the function will silently return. Returned RouteChangeCallback.Unregister method should be used
|
||||
// to unregister.
|
||||
func RegisterRouteChangeCallback(callback func(notificationType MibNotificationType, route *MibIPforwardRow2)) (*RouteChangeCallback, error) {
|
||||
s := &RouteChangeCallback{cb: callback}
|
||||
|
||||
routeChangeAddRemoveMutex.Lock()
|
||||
defer routeChangeAddRemoveMutex.Unlock()
|
||||
|
||||
routeChangeMutex.Lock()
|
||||
defer routeChangeMutex.Unlock()
|
||||
|
||||
routeChangeCallbacks[s] = true
|
||||
|
||||
if routeChangeHandle == 0 {
|
||||
err := notifyRouteChange2(windows.AF_UNSPEC, windows.NewCallback(routeChanged), 0, false, &routeChangeHandle)
|
||||
if err != nil {
|
||||
delete(routeChangeCallbacks, s)
|
||||
routeChangeHandle = 0
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// Unregister unregisters the callback.
|
||||
func (callback *RouteChangeCallback) Unregister() error {
|
||||
routeChangeAddRemoveMutex.Lock()
|
||||
defer routeChangeAddRemoveMutex.Unlock()
|
||||
|
||||
routeChangeMutex.Lock()
|
||||
delete(routeChangeCallbacks, callback)
|
||||
removeIt := len(routeChangeCallbacks) == 0 && routeChangeHandle != 0
|
||||
routeChangeMutex.Unlock()
|
||||
|
||||
callback.wait.Wait()
|
||||
|
||||
if removeIt {
|
||||
err := cancelMibChangeNotify2(routeChangeHandle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
routeChangeHandle = 0
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func routeChanged(callerContext uintptr, row *MibIPforwardRow2, notificationType MibNotificationType) uintptr {
|
||||
rowCopy := *row
|
||||
routeChangeMutex.Lock()
|
||||
for cb := range routeChangeCallbacks {
|
||||
cb.wait.Add(1)
|
||||
go func(cb *RouteChangeCallback) {
|
||||
cb.cb(notificationType, &rowCopy)
|
||||
cb.wait.Done()
|
||||
}(cb)
|
||||
}
|
||||
routeChangeMutex.Unlock()
|
||||
return 0
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue