diff --git a/go.mod b/go.mod index 897bf8860c..d0874743ce 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,7 @@ require ( github.com/skycoin/dmsg v1.3.17 github.com/skycoin/skycoin v0.27.1 github.com/skycoin/skycoin-service-discovery v0.0.0-20231221001759-d1af6ec27db1 - github.com/skycoin/skywire-services v0.0.0-20231221001820-3212895ddf12 + github.com/skycoin/skywire-services v0.0.0-20240207001624-ebee7346e526 github.com/skycoin/skywire-utilities v1.3.17 github.com/skycoin/systray v1.10.0 github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 @@ -47,7 +47,7 @@ require ( golang.org/x/net v0.14.0 golang.org/x/sync v0.3.0 golang.org/x/sys v0.15.0 - golang.zx2c4.com/wireguard v0.0.20200320 + golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675 ) require ( @@ -150,6 +150,7 @@ require ( golang.org/x/term v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect + golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 28a2efc000..b57fbb68c1 100644 --- a/go.sum +++ b/go.sum @@ -444,6 +444,8 @@ github.com/skycoin/skycoin-service-discovery v0.0.0-20231221001759-d1af6ec27db1 github.com/skycoin/skycoin-service-discovery v0.0.0-20231221001759-d1af6ec27db1/go.mod h1:6VwZDwW4aO6fucuZKiJQ4PnnVYi5CfN/eHcK8F0C05M= github.com/skycoin/skywire-services v0.0.0-20231221001820-3212895ddf12 h1:fic0WKltARs0JnbNFcKesijNgcPOeJh7CsFs/KLZoJw= github.com/skycoin/skywire-services v0.0.0-20231221001820-3212895ddf12/go.mod h1:HYqBsmgat3wTk1zwGLNj3q5N3iCpJOwYOuLexqKH02k= +github.com/skycoin/skywire-services v0.0.0-20240207001624-ebee7346e526 h1:9Fs12yw4gpNwb/D7FtRZj1BfOMM3GkWt7NYM16K0+tM= +github.com/skycoin/skywire-services v0.0.0-20240207001624-ebee7346e526/go.mod h1:KfJQ6p13LpG+gBwzASh5ehZSi059aX44E/E4wQM2780= github.com/skycoin/skywire-utilities v1.3.17 h1:89aPdViJxhMpjEJbByQ02W8anX6Oxt68OeSxAENBlFI= github.com/skycoin/skywire-utilities v1.3.17/go.mod h1:yFKWpL1bDRPKU3uK+cTF4PnYUMe+eyIj5N2bk4sF5Cw= github.com/skycoin/systray v1.10.0 h1:fQZJHMylpVvfmOOTLvUssfyHVDoC8Idx6Ba2BlLEuGg= @@ -688,6 +690,10 @@ 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-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= +golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= +golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675 h1:/J/RVnr7ng4fWPRH3xa4WtBJ1Jp+Auu4YNLmGiPv5QU= +golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675/go.mod h1:whfbyDBt09xhCYQWtO2+3UVjlaq6/9hDZrjg2ZE6SyA= golang.zx2c4.com/wireguard v0.0.20200320 h1:1vE6zVeO7fix9cJX1Z9ZQ+ikPIIx7vIyU0o0tLDD88g= golang.zx2c4.com/wireguard v0.0.20200320/go.mod h1:lDian4Sw4poJ04SgHh35nzMVwGSYlPumkdnHcucAQoY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/vendor/github.com/skycoin/skywire-services/cmd/public-visor-monitor/commands/root.go b/vendor/github.com/skycoin/skywire-services/cmd/public-visor-monitor/commands/root.go index ad85043e70..8343676815 100644 --- a/vendor/github.com/skycoin/skywire-services/cmd/public-visor-monitor/commands/root.go +++ b/vendor/github.com/skycoin/skywire-services/cmd/public-visor-monitor/commands/root.go @@ -59,6 +59,7 @@ var RootCmd = &cobra.Command{ } mLogger := logging.NewMasterLogger() + lvl, err := logging.LevelFromString(logLvl) if err != nil { mLogger.Fatal("Invalid loglvl detected") diff --git a/vendor/github.com/skycoin/skywire-services/cmd/tpd-monitor/commands/root.go b/vendor/github.com/skycoin/skywire-services/cmd/tpd-monitor/commands/root.go index 13df606efe..f88273b9ba 100644 --- a/vendor/github.com/skycoin/skywire-services/cmd/tpd-monitor/commands/root.go +++ b/vendor/github.com/skycoin/skywire-services/cmd/tpd-monitor/commands/root.go @@ -35,7 +35,7 @@ var ( func init() { RootCmd.Flags().StringVarP(&addr, "addr", "a", ":9080", "address to bind to.\033[0m") RootCmd.Flags().DurationVarP(&sleepDeregistration, "sleep-deregistration", "s", 10, "Sleep time for deregistration process in minutes\033[0m") - RootCmd.Flags().StringVarP(&confPath, "config", "c", "dmsg-monitor.json", "config file location.\033[0m") + RootCmd.Flags().StringVarP(&confPath, "config", "c", "tpd-monitor.json", "config file location.\033[0m") RootCmd.Flags().StringVarP(&logLvl, "loglvl", "l", "info", "set log level one of: info, error, warn, debug, trace, panic") RootCmd.Flags().StringVar(&dmsgURL, "dmsg-url", "", "url to dmsg data.\033[0m") RootCmd.Flags().StringVar(&tpdURL, "tpd-url", "", "url to transport discovery.\033[0m") @@ -105,26 +105,26 @@ var RootCmd = &cobra.Command{ monitorSign, _ := cipher.SignPayload([]byte(conf.PK.Hex()), conf.SK) //nolint - var monitorConfig api.DMSGMonitorConfig + var monitorConfig api.TpdMonitorConfig monitorConfig.PK = conf.PK monitorConfig.Sign = monitorSign - dmsgMonitorAPI := api.New(logger, srvURLs, monitorConfig) + tpdMonitorAPI := api.New(logger, srvURLs, monitorConfig) ctx, cancel := cmdutil.SignalContext(context.Background(), logger) defer cancel() - go dmsgMonitorAPI.InitDeregistrationLoop(ctx, conf, sleepDeregistration) + go tpdMonitorAPI.InitDeregistrationLoop(ctx, conf, sleepDeregistration) go func() { - if err := tcpproxy.ListenAndServe(addr, dmsgMonitorAPI); err != nil { + if err := tcpproxy.ListenAndServe(addr, tpdMonitorAPI); err != nil { logger.Errorf("serve: %v", err) cancel() } }() <-ctx.Done() - if err := dmsgMonitorAPI.Visor.Close(); err != nil { + if err := tpdMonitorAPI.Visor.Close(); err != nil { logger.WithError(err).Error("Visor closed with error.") } }, diff --git a/vendor/github.com/skycoin/skywire-services/cmd/transport-discovery/commands/root.go b/vendor/github.com/skycoin/skywire-services/cmd/transport-discovery/commands/root.go index 6165f55755..1aeea99e4c 100644 --- a/vendor/github.com/skycoin/skywire-services/cmd/transport-discovery/commands/root.go +++ b/vendor/github.com/skycoin/skywire-services/cmd/transport-discovery/commands/root.go @@ -21,6 +21,7 @@ import ( "github.com/skycoin/skywire-utilities/pkg/httpauth" "github.com/skycoin/skywire-utilities/pkg/logging" "github.com/skycoin/skywire-utilities/pkg/metricsutil" + "github.com/skycoin/skywire-utilities/pkg/skyenv" "github.com/skycoin/skywire-utilities/pkg/storeconfig" "github.com/skycoin/skywire-utilities/pkg/tcpproxy" "github.com/spf13/cobra" @@ -38,19 +39,21 @@ const ( ) var ( - addr string - metricsAddr string - redisURL string - redisPoolSize int - pgHost string - pgPort string - syslogAddr string - logLvl string - tag string - testing bool - dmsgDisc string - sk cipher.SecKey - dmsgPort uint16 + addr string + metricsAddr string + redisURL string + redisPoolSize int + pgHost string + pgPort string + syslogAddr string + logLvl string + tag string + testing bool + dmsgDisc string + whitelistKeys string + testEnvironment bool + sk cipher.SecKey + dmsgPort uint16 ) func init() { @@ -65,6 +68,8 @@ func init() { RootCmd.Flags().StringVar(&tag, "tag", "transport_discovery", "logging tag\033[0m") RootCmd.Flags().BoolVarP(&testing, "testing", "t", false, "enable testing to start without redis\033[0m") RootCmd.Flags().StringVar(&dmsgDisc, "dmsg-disc", "http://dmsgd.skywire.skycoin.com", "url of dmsg-discovery\033[0m") + RootCmd.Flags().StringVar(&whitelistKeys, "whitelist-keys", "", "list of whitelisted keys of network monitor used for deregistration\033[0m") + RootCmd.Flags().BoolVar(&testEnvironment, "test-environment", false, "distinguished between prod and test environment\033[0m") RootCmd.Flags().Var(&sk, "sk", "dmsg secret key\r") RootCmd.Flags().Uint16Var(&dmsgPort, "dmsgPort", dmsg.DefaultDmsgHTTPPort, "dmsg port value\r") var helpflag bool @@ -111,6 +116,21 @@ var RootCmd = &cobra.Command{ logging.SetLevel(lvl) + var whitelistPKs []string + if whitelistKeys != "" { + whitelistPKs = strings.Split(whitelistKeys, ",") + } else { + if testEnvironment { + whitelistPKs = strings.Split(skyenv.TestNetworkMonitorPKs, ",") + } else { + whitelistPKs = strings.Split(skyenv.NetworkMonitorPKs, ",") + } + } + + for _, v := range whitelistPKs { + api.WhitelistPKs.Set(v) + } + if syslogAddr != "" { hook, err := logrussyslog.NewSyslogHook("udp", syslogAddr, syslog.LOG_INFO, tag) if err != nil { diff --git a/vendor/github.com/skycoin/skywire-services/pkg/dmsg-monitor/api/api.go b/vendor/github.com/skycoin/skywire-services/pkg/dmsg-monitor/api/api.go index 9a50196d16..080f2c6c08 100644 --- a/vendor/github.com/skycoin/skywire-services/pkg/dmsg-monitor/api/api.go +++ b/vendor/github.com/skycoin/skywire-services/pkg/dmsg-monitor/api/api.go @@ -7,6 +7,7 @@ import ( "encoding/json" "fmt" "io" + "math/rand" "net/http" "net/url" "strings" @@ -169,7 +170,10 @@ func (api *API) dmsgDeregistration(uptimes map[string]bool) { api.logger.Warnf("Error occur during get dmsg clients list due to %s", err) return } - + //randomize the order of the dmsg entries + rand.Shuffle(len(clients), func(i, j int) { + clients[i], clients[j] = clients[j], clients[i] + }) // check dmsg clients either alive or dead checkerConfig := dmsgCheckerConfig{ wg: new(sync.WaitGroup), @@ -424,7 +428,20 @@ func whitelistedPKs() map[string]bool { for _, pk := range strings.Split(utilenv.TestNetworkMonitorPKs, ",") { whitelistedPKs[pk] = true } - whitelistedPKs[utilenv.RouteSetupPKs] = true - whitelistedPKs[utilenv.TestRouteSetupPKs] = true + for _, pk := range strings.Split(utilenv.RouteSetupPKs, ",") { + whitelistedPKs[pk] = true + } + for _, pk := range strings.Split(utilenv.TestRouteSetupPKs, ",") { + whitelistedPKs[pk] = true + } + for _, pk := range strings.Split(utilenv.TPSetupPKs, ",") { + whitelistedPKs[pk] = true + } + for _, pk := range strings.Split(utilenv.TestTPSetupPKs, ",") { + whitelistedPKs[pk] = true + } + for _, pk := range strings.Split(utilenv.SurveyWhitelistPKs, ",") { + whitelistedPKs[pk] = true + } return whitelistedPKs } diff --git a/vendor/github.com/skycoin/skywire-services/pkg/liveness-checker/api/api.go b/vendor/github.com/skycoin/skywire-services/pkg/liveness-checker/api/api.go index 36227c59da..ad44425735 100644 --- a/vendor/github.com/skycoin/skywire-services/pkg/liveness-checker/api/api.go +++ b/vendor/github.com/skycoin/skywire-services/pkg/liveness-checker/api/api.go @@ -285,7 +285,7 @@ func (api *API) checkAddressResolver(ctx context.Context) { err = api.store.AddServiceSummary(ctx, "address-resolver", ss) if err != nil { - api.logger.WithError(err).Warn("Failed to add address-resolver service summarry to store.") + api.logger.WithError(err).Warn("Failed to add address-resolver service summary to store.") } api.logger.Info("address-resolver liveness check complete.") } @@ -317,7 +317,7 @@ func (api *API) checkServiceDiscovery(ctx context.Context) { err = api.store.AddServiceSummary(ctx, "service-discovery", ss) if err != nil { - api.logger.WithError(err).Warn("Failed to add service-discovery service summarry to store.") + api.logger.WithError(err).Warn("Failed to add service-discovery service summary to store.") } api.logger.Info("service-discovery liveness check complete.") } @@ -351,7 +351,7 @@ func (api *API) checkTransportDiscovery(ctx context.Context) { err = api.store.AddServiceSummary(ctx, "transport-discovery", ss) if err != nil { - api.logger.WithError(err).Warn("Failed to add transport-discovery service summarry to store.") + api.logger.WithError(err).Warn("Failed to add transport-discovery service summary to store.") } api.logger.Info("transport-discovery liveness check complete.") } @@ -398,7 +398,7 @@ func (api *API) checkDMSGDiscovery(ctx context.Context) { err = api.store.AddServiceSummary(ctx, "dmsg-discovery", ss) if err != nil { - api.logger.WithError(err).Warn("Failed to add dmsg-discovery service summarry to store.") + api.logger.WithError(err).Warn("Failed to add dmsg-discovery service summary to store.") } api.logger.Info("dmsg-discovery liveness check complete.") @@ -428,7 +428,7 @@ func (api *API) checkDMSGServers(ctx context.Context, disc disc.APIClient, serve serviceName := "dmsg-server:" + server.Server.Address err := api.store.AddServiceSummary(ctx, serviceName, ss) if err != nil { - api.logger.WithError(err).Warnf("Failed to add %v serviceName service summarry to store.", serviceName) + api.logger.WithError(err).Warnf("Failed to add %v serviceName service summary to store.", serviceName) } api.logger.Infof("%v liveness check complete.", serviceName) } @@ -464,7 +464,7 @@ func (api *API) checkRouteFinder(ctx context.Context) { err = api.store.AddServiceSummary(ctx, "route-finder", ss) if err != nil { - api.logger.WithError(err).Warn("Failed to add route-finder service summarry to store.") + api.logger.WithError(err).Warn("Failed to add route-finder service summary to store.") } api.logger.Info("route-finder liveness check complete.") } @@ -508,7 +508,7 @@ func (api *API) checkUptimeTracker(ctx context.Context) { err = api.store.AddServiceSummary(ctx, "uptime-tracker", ss) if err != nil { - api.logger.WithError(err).Warn("Failed to add uptime-tracker service summarry to store.") + api.logger.WithError(err).Warn("Failed to add uptime-tracker service summary to store.") } api.logger.Info("uptime-tracker liveness check complete.") } @@ -557,7 +557,7 @@ func (api *API) checkIPService(ctx context.Context) { err = api.store.AddServiceSummary(ctx, "ip-service", ss) if err != nil { - api.logger.WithError(err).Warn("Failed to add ip-service service summarry to store.") + api.logger.WithError(err).Warn("Failed to add ip-service service summary to store.") } api.logger.Info("ip-service liveness check complete.") } @@ -586,7 +586,7 @@ func (api *API) checkStunServers(ctx context.Context) { serviceName := "stunserver:" + stunServer err = api.store.AddServiceSummary(ctx, serviceName, ss) if err != nil { - api.logger.WithError(err).Warn("Failed to add ip-service service summarry to store.") + api.logger.WithError(err).Warn("Failed to add ip-service service summary to store.") } api.logger.Infof("%v liveness check complete.", serviceName) } diff --git a/vendor/github.com/skycoin/skywire-services/pkg/tpd-monitor/api/api.go b/vendor/github.com/skycoin/skywire-services/pkg/tpd-monitor/api/api.go index 55d0321c5b..60fce30be8 100644 --- a/vendor/github.com/skycoin/skywire-services/pkg/tpd-monitor/api/api.go +++ b/vendor/github.com/skycoin/skywire-services/pkg/tpd-monitor/api/api.go @@ -47,8 +47,8 @@ type API struct { whitelistedPKs map[string]bool } -// DMSGMonitorConfig is struct for Keys and Sign value of dmsg monitor -type DMSGMonitorConfig struct { +// TpdMonitorConfig is struct for Keys and Sign value of tpd monitor +type TpdMonitorConfig struct { PK cipher.PubKey Sign cipher.Sig } @@ -72,7 +72,7 @@ type Error struct { } // New returns a new *chi.Mux object, which can be started as a server -func New(logger *logging.Logger, srvURLs ServicesURLs, monitorConfig DMSGMonitorConfig) *API { +func New(logger *logging.Logger, srvURLs ServicesURLs, monitorConfig TpdMonitorConfig) *API { api := &API{ dmsgURL: srvURLs.DMSG, @@ -291,7 +291,7 @@ func getARData(url string) (map[string]map[string]bool, error) { } func (api *API) tpdDeregister(tps []string) { - err := api.deregisterRequest(tps, api.dmsgURL+"/deregister", "tp discovery") + err := api.deregisterRequest(tps, api.tpdURL+"/transports/deregister", "tp discovery") if err != nil { api.logger.Warn(err) return @@ -331,7 +331,7 @@ func (api *API) deregisterRequest(keys []string, rawReqURL, service string) erro }(res.Body) if res.StatusCode != http.StatusOK { - return fmt.Errorf("Error deregister keys from %s : %s", service, err) + return fmt.Errorf("Error on deregister keys from %s : res.StatusCode %d", service, res.StatusCode) } return nil diff --git a/vendor/github.com/skycoin/skywire-services/pkg/transport-discovery/api/api.go b/vendor/github.com/skycoin/skywire-services/pkg/transport-discovery/api/api.go index aeb22591f5..6ac2ac789c 100644 --- a/vendor/github.com/skycoin/skywire-services/pkg/transport-discovery/api/api.go +++ b/vendor/github.com/skycoin/skywire-services/pkg/transport-discovery/api/api.go @@ -98,11 +98,11 @@ func New(log logrus.FieldLogger, s store.Store, nonceStore httpauth.NonceStore, r.Get("/transports/edge:{edge}", api.getTransportByEdge) r.Post("/transports/", api.registerTransport) r.Delete("/transports/id:{id}", api.deleteTransport) - r.Delete("/transports/deregister", api.deregisterTransport) }) r.Get("/health", api.health) r.Get("/all-transports", api.getAllTransports) + r.Delete("/transports/deregister", api.deregisterTransport) r.Post("/statuses", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusGone) }) diff --git a/vendor/golang.zx2c4.com/wireguard/COPYING b/vendor/golang.zx2c4.com/wintun/LICENSE similarity index 100% rename from vendor/golang.zx2c4.com/wireguard/COPYING rename to vendor/golang.zx2c4.com/wintun/LICENSE diff --git a/vendor/golang.zx2c4.com/wintun/README.md b/vendor/golang.zx2c4.com/wintun/README.md new file mode 100644 index 0000000000..bd73e0ff5f --- /dev/null +++ b/vendor/golang.zx2c4.com/wintun/README.md @@ -0,0 +1,9 @@ +## wintun-go + +This contains bindings to use [Wintun](https://www.wintun.net) from Go. + +```go +import "golang.zx2c4.com/wintun" +``` + +- [Documentation](https://pkg.go.dev/golang.zx2c4.com/wintun) diff --git a/vendor/golang.zx2c4.com/wintun/dll.go b/vendor/golang.zx2c4.com/wintun/dll.go new file mode 100644 index 0000000000..ba9cad7bda --- /dev/null +++ b/vendor/golang.zx2c4.com/wintun/dll.go @@ -0,0 +1,130 @@ +//go:build windows + +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2017-2021 WireGuard LLC. All Rights Reserved. + */ + +package wintun + +import ( + "fmt" + "sync" + "sync/atomic" + "unsafe" + + "golang.org/x/sys/windows" +) + +func newLazyDLL(name string, onLoad func(d *lazyDLL)) *lazyDLL { + return &lazyDLL{Name: name, onLoad: onLoad} +} + +func (d *lazyDLL) NewProc(name string) *lazyProc { + return &lazyProc{dll: d, Name: name} +} + +type lazyProc struct { + Name string + mu sync.Mutex + dll *lazyDLL + addr uintptr +} + +func (p *lazyProc) Find() error { + if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.addr))) != nil { + return nil + } + p.mu.Lock() + defer p.mu.Unlock() + if p.addr != 0 { + return nil + } + + err := p.dll.Load() + if err != nil { + return fmt.Errorf("Error loading %v DLL: %w", p.dll.Name, err) + } + addr, err := p.nameToAddr() + if err != nil { + return fmt.Errorf("Error getting %v address: %w", p.Name, err) + } + + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.addr)), unsafe.Pointer(addr)) + return nil +} + +func (p *lazyProc) Addr() uintptr { + err := p.Find() + if err != nil { + panic(err) + } + return p.addr +} + +type lazyDLL struct { + Name string + mu sync.Mutex + module windows.Handle + onLoad func(d *lazyDLL) +} + +func (d *lazyDLL) Load() error { + if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.module))) != nil { + return nil + } + d.mu.Lock() + defer d.mu.Unlock() + if d.module != 0 { + return nil + } + + const ( + LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 0x00000200 + LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 + ) + module, err := windows.LoadLibraryEx(d.Name, 0, LOAD_LIBRARY_SEARCH_APPLICATION_DIR|LOAD_LIBRARY_SEARCH_SYSTEM32) + if err != nil { + return fmt.Errorf("Unable to load library: %w", err) + } + + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.module)), unsafe.Pointer(module)) + if d.onLoad != nil { + d.onLoad(d) + } + return nil +} + +func (p *lazyProc) nameToAddr() (uintptr, error) { + return windows.GetProcAddress(p.dll.module, p.Name) +} + +// Version returns the version of the Wintun DLL. +func Version() string { + if modwintun.Load() != nil { + return "unknown" + } + resInfo, err := windows.FindResource(modwintun.module, windows.ResourceID(1), windows.RT_VERSION) + if err != nil { + return "unknown" + } + data, err := windows.LoadResourceData(modwintun.module, resInfo) + if err != nil { + return "unknown" + } + + var fixedInfo *windows.VS_FIXEDFILEINFO + fixedInfoLen := uint32(unsafe.Sizeof(*fixedInfo)) + err = windows.VerQueryValue(unsafe.Pointer(&data[0]), `\`, unsafe.Pointer(&fixedInfo), &fixedInfoLen) + if err != nil { + return "unknown" + } + version := fmt.Sprintf("%d.%d", (fixedInfo.FileVersionMS>>16)&0xff, (fixedInfo.FileVersionMS>>0)&0xff) + if nextNibble := (fixedInfo.FileVersionLS >> 16) & 0xff; nextNibble != 0 { + version += fmt.Sprintf(".%d", nextNibble) + } + if nextNibble := (fixedInfo.FileVersionLS >> 0) & 0xff; nextNibble != 0 { + version += fmt.Sprintf(".%d", nextNibble) + } + return version +} diff --git a/vendor/golang.zx2c4.com/wintun/session.go b/vendor/golang.zx2c4.com/wintun/session.go new file mode 100644 index 0000000000..45e97a0f7d --- /dev/null +++ b/vendor/golang.zx2c4.com/wintun/session.go @@ -0,0 +1,92 @@ +//go:build windows + +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2017-2021 WireGuard LLC. All Rights Reserved. + */ + +package wintun + +import ( + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +type Session struct { + handle uintptr +} + +const ( + PacketSizeMax = 0xffff // Maximum packet size + RingCapacityMin = 0x20000 // Minimum ring capacity (128 kiB) + RingCapacityMax = 0x4000000 // Maximum ring capacity (64 MiB) +) + +// Packet with data +type Packet struct { + Next *Packet // Pointer to next packet in queue + Size uint32 // Size of packet (max WINTUN_MAX_IP_PACKET_SIZE) + Data *[PacketSizeMax]byte // Pointer to layer 3 IPv4 or IPv6 packet +} + +var ( + procWintunAllocateSendPacket = modwintun.NewProc("WintunAllocateSendPacket") + procWintunEndSession = modwintun.NewProc("WintunEndSession") + procWintunGetReadWaitEvent = modwintun.NewProc("WintunGetReadWaitEvent") + procWintunReceivePacket = modwintun.NewProc("WintunReceivePacket") + procWintunReleaseReceivePacket = modwintun.NewProc("WintunReleaseReceivePacket") + procWintunSendPacket = modwintun.NewProc("WintunSendPacket") + procWintunStartSession = modwintun.NewProc("WintunStartSession") +) + +func (wintun *Adapter) StartSession(capacity uint32) (session Session, err error) { + r0, _, e1 := syscall.Syscall(procWintunStartSession.Addr(), 2, uintptr(wintun.handle), uintptr(capacity), 0) + if r0 == 0 { + err = e1 + } else { + session = Session{r0} + } + return +} + +func (session Session) End() { + syscall.Syscall(procWintunEndSession.Addr(), 1, session.handle, 0, 0) + session.handle = 0 +} + +func (session Session) ReadWaitEvent() (handle windows.Handle) { + r0, _, _ := syscall.Syscall(procWintunGetReadWaitEvent.Addr(), 1, session.handle, 0, 0) + handle = windows.Handle(r0) + return +} + +func (session Session) ReceivePacket() (packet []byte, err error) { + var packetSize uint32 + r0, _, e1 := syscall.Syscall(procWintunReceivePacket.Addr(), 2, session.handle, uintptr(unsafe.Pointer(&packetSize)), 0) + if r0 == 0 { + err = e1 + return + } + packet = unsafe.Slice((*byte)(unsafe.Pointer(r0)), packetSize) + return +} + +func (session Session) ReleaseReceivePacket(packet []byte) { + syscall.Syscall(procWintunReleaseReceivePacket.Addr(), 2, session.handle, uintptr(unsafe.Pointer(&packet[0])), 0) +} + +func (session Session) AllocateSendPacket(packetSize int) (packet []byte, err error) { + r0, _, e1 := syscall.Syscall(procWintunAllocateSendPacket.Addr(), 2, session.handle, uintptr(packetSize), 0) + if r0 == 0 { + err = e1 + return + } + packet = unsafe.Slice((*byte)(unsafe.Pointer(r0)), packetSize) + return +} + +func (session Session) SendPacket(packet []byte) { + syscall.Syscall(procWintunSendPacket.Addr(), 2, session.handle, uintptr(unsafe.Pointer(&packet[0])), 0) +} diff --git a/vendor/golang.zx2c4.com/wintun/wintun.go b/vendor/golang.zx2c4.com/wintun/wintun.go new file mode 100644 index 0000000000..1ffd62fb5d --- /dev/null +++ b/vendor/golang.zx2c4.com/wintun/wintun.go @@ -0,0 +1,167 @@ +//go:build windows + +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2017-2021 WireGuard LLC. All Rights Reserved. + */ + +package wintun + +import ( + "log" + "runtime" + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +type loggerLevel int + +const ( + logInfo loggerLevel = iota + logWarn + logErr +) + +const AdapterNameMax = 128 + +type Adapter struct { + handle uintptr +} + +var ( + modwintun = newLazyDLL("wintun.dll", setupLogger) + procWintunCreateAdapter = modwintun.NewProc("WintunCreateAdapter") + procWintunOpenAdapter = modwintun.NewProc("WintunOpenAdapter") + procWintunCloseAdapter = modwintun.NewProc("WintunCloseAdapter") + procWintunDeleteDriver = modwintun.NewProc("WintunDeleteDriver") + procWintunGetAdapterLUID = modwintun.NewProc("WintunGetAdapterLUID") + procWintunGetRunningDriverVersion = modwintun.NewProc("WintunGetRunningDriverVersion") +) + +type TimestampedWriter interface { + WriteWithTimestamp(p []byte, ts int64) (n int, err error) +} + +func logMessage(level loggerLevel, timestamp uint64, msg *uint16) int { + if tw, ok := log.Default().Writer().(TimestampedWriter); ok { + tw.WriteWithTimestamp([]byte(log.Default().Prefix()+windows.UTF16PtrToString(msg)), (int64(timestamp)-116444736000000000)*100) + } else { + log.Println(windows.UTF16PtrToString(msg)) + } + return 0 +} + +func setupLogger(dll *lazyDLL) { + var callback uintptr + if runtime.GOARCH == "386" { + callback = windows.NewCallback(func(level loggerLevel, timestampLow, timestampHigh uint32, msg *uint16) int { + return logMessage(level, uint64(timestampHigh)<<32|uint64(timestampLow), msg) + }) + } else if runtime.GOARCH == "arm" { + callback = windows.NewCallback(func(level loggerLevel, _, timestampLow, timestampHigh uint32, msg *uint16) int { + return logMessage(level, uint64(timestampHigh)<<32|uint64(timestampLow), msg) + }) + } else if runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64" { + callback = windows.NewCallback(logMessage) + } + syscall.Syscall(dll.NewProc("WintunSetLogger").Addr(), 1, callback, 0, 0) +} + +func closeAdapter(wintun *Adapter) { + syscall.Syscall(procWintunCloseAdapter.Addr(), 1, wintun.handle, 0, 0) +} + +// CreateAdapter creates a Wintun adapter. name is the cosmetic name of the adapter. +// tunnelType represents the type of adapter and should be "Wintun". requestedGUID is +// the GUID of the created network adapter, which then influences NLA generation +// deterministically. If it is set to nil, the GUID is chosen by the system at random, +// and hence a new NLA entry is created for each new adapter. +func CreateAdapter(name string, tunnelType string, requestedGUID *windows.GUID) (wintun *Adapter, err error) { + var name16 *uint16 + name16, err = windows.UTF16PtrFromString(name) + if err != nil { + return + } + var tunnelType16 *uint16 + tunnelType16, err = windows.UTF16PtrFromString(tunnelType) + if err != nil { + return + } + if err := procWintunCreateAdapter.Find(); err != nil { + return nil, err + } + r0, _, e1 := syscall.Syscall(procWintunCreateAdapter.Addr(), 3, uintptr(unsafe.Pointer(name16)), uintptr(unsafe.Pointer(tunnelType16)), uintptr(unsafe.Pointer(requestedGUID))) + if r0 == 0 { + err = e1 + return + } + wintun = &Adapter{handle: r0} + runtime.SetFinalizer(wintun, closeAdapter) + return +} + +// OpenAdapter opens an existing Wintun adapter by name. +func OpenAdapter(name string) (wintun *Adapter, err error) { + var name16 *uint16 + name16, err = windows.UTF16PtrFromString(name) + if err != nil { + return + } + if err := procWintunOpenAdapter.Find(); err != nil { + return nil, err + } + r0, _, e1 := syscall.Syscall(procWintunOpenAdapter.Addr(), 1, uintptr(unsafe.Pointer(name16)), 0, 0) + if r0 == 0 { + err = e1 + return + } + wintun = &Adapter{handle: r0} + runtime.SetFinalizer(wintun, closeAdapter) + return +} + +// Close closes a Wintun adapter. +func (wintun *Adapter) Close() (err error) { + if err := procWintunCloseAdapter.Find(); err != nil { + return err + } + runtime.SetFinalizer(wintun, nil) + r1, _, e1 := syscall.Syscall(procWintunCloseAdapter.Addr(), 1, wintun.handle, 0, 0) + if r1 == 0 { + err = e1 + } + return +} + +// Uninstall removes the driver from the system if no drivers are currently in use. +func Uninstall() (err error) { + if err := procWintunDeleteDriver.Find(); err != nil { + return err + } + r1, _, e1 := syscall.Syscall(procWintunDeleteDriver.Addr(), 0, 0, 0, 0) + if r1 == 0 { + err = e1 + } + return +} + +// RunningVersion returns the version of the loaded driver. +func RunningVersion() (version uint32, err error) { + if err := procWintunGetRunningDriverVersion.Find(); err != nil { + return 0, err + } + r0, _, e1 := syscall.Syscall(procWintunGetRunningDriverVersion.Addr(), 0, 0, 0, 0) + version = uint32(r0) + if version == 0 { + err = e1 + } + return +} + +// LUID returns the LUID of the adapter. +func (wintun *Adapter) LUID() (luid uint64) { + syscall.Syscall(procWintunGetAdapterLUID.Addr(), 2, uintptr(wintun.handle), uintptr(unsafe.Pointer(&luid)), 0) + return +} diff --git a/vendor/golang.zx2c4.com/wireguard/LICENSE b/vendor/golang.zx2c4.com/wireguard/LICENSE new file mode 100644 index 0000000000..f85e365de0 --- /dev/null +++ b/vendor/golang.zx2c4.com/wireguard/LICENSE @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/golang.zx2c4.com/wireguard/rwcancel/fdset.go b/vendor/golang.zx2c4.com/wireguard/rwcancel/fdset.go deleted file mode 100644 index 28746e66e8..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/rwcancel/fdset.go +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2017-2019 WireGuard LLC. All Rights Reserved. - */ - -package rwcancel - -import "golang.org/x/sys/unix" - -type fdSet struct { - unix.FdSet -} - -func (fdset *fdSet) set(i int) { - bits := 32 << (^uint(0) >> 63) - fdset.Bits[i/bits] |= 1 << uint(i%bits) -} - -func (fdset *fdSet) check(i int) bool { - bits := 32 << (^uint(0) >> 63) - return (fdset.Bits[i/bits] & (1 << uint(i%bits))) != 0 -} diff --git a/vendor/golang.zx2c4.com/wireguard/rwcancel/rwcancel.go b/vendor/golang.zx2c4.com/wireguard/rwcancel/rwcancel.go index 808e691836..63e1510b10 100644 --- a/vendor/golang.zx2c4.com/wireguard/rwcancel/rwcancel.go +++ b/vendor/golang.zx2c4.com/wireguard/rwcancel/rwcancel.go @@ -1,8 +1,12 @@ +//go:build !windows && !js + /* SPDX-License-Identifier: MIT * - * Copyright (C) 2017-2019 WireGuard LLC. All Rights Reserved. + * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved. */ +// Package rwcancel implements cancelable read/write operations on +// a file descriptor. package rwcancel import ( @@ -13,13 +17,6 @@ import ( "golang.org/x/sys/unix" ) -func max(a, b int) int { - if a > b { - return a - } - return b -} - type RWCancel struct { fd int closingReader *os.File @@ -42,27 +39,16 @@ func NewRWCancel(fd int) (*RWCancel, error) { } func RetryAfterError(err error) bool { - if pe, ok := err.(*os.PathError); ok { - err = pe.Err - } - if errno, ok := err.(syscall.Errno); ok { - switch errno { - case syscall.EAGAIN, syscall.EINTR: - return true - } - - } - return false + return errors.Is(err, syscall.EAGAIN) || errors.Is(err, syscall.EINTR) } func (rw *RWCancel) ReadyRead() bool { - closeFd := int(rw.closingReader.Fd()) - fdset := fdSet{} - fdset.set(rw.fd) - fdset.set(closeFd) + closeFd := int32(rw.closingReader.Fd()) + + pollFds := []unix.PollFd{{Fd: int32(rw.fd), Events: unix.POLLIN}, {Fd: closeFd, Events: unix.POLLIN}} var err error for { - err = unixSelect(max(rw.fd, closeFd)+1, &fdset.FdSet, nil, nil, nil) + _, err = unix.Poll(pollFds, -1) if err == nil || !RetryAfterError(err) { break } @@ -70,20 +56,18 @@ func (rw *RWCancel) ReadyRead() bool { if err != nil { return false } - if fdset.check(closeFd) { + if pollFds[1].Revents != 0 { return false } - return fdset.check(rw.fd) + return pollFds[0].Revents != 0 } func (rw *RWCancel) ReadyWrite() bool { - closeFd := int(rw.closingReader.Fd()) - fdset := fdSet{} - fdset.set(rw.fd) - fdset.set(closeFd) + closeFd := int32(rw.closingReader.Fd()) + pollFds := []unix.PollFd{{Fd: int32(rw.fd), Events: unix.POLLOUT}, {Fd: closeFd, Events: unix.POLLOUT}} var err error for { - err = unixSelect(max(rw.fd, closeFd)+1, nil, &fdset.FdSet, nil, nil) + _, err = unix.Poll(pollFds, -1) if err == nil || !RetryAfterError(err) { break } @@ -91,10 +75,11 @@ func (rw *RWCancel) ReadyWrite() bool { if err != nil { return false } - if fdset.check(closeFd) { + + if pollFds[1].Revents != 0 { return false } - return fdset.check(rw.fd) + return pollFds[0].Revents != 0 } func (rw *RWCancel) Read(p []byte) (n int, err error) { @@ -104,7 +89,7 @@ func (rw *RWCancel) Read(p []byte) (n int, err error) { return n, err } if !rw.ReadyRead() { - return 0, errors.New("fd closed") + return 0, os.ErrClosed } } } @@ -116,7 +101,7 @@ func (rw *RWCancel) Write(p []byte) (n int, err error) { return n, err } if !rw.ReadyWrite() { - return 0, errors.New("fd closed") + return 0, os.ErrClosed } } } @@ -125,3 +110,8 @@ func (rw *RWCancel) Cancel() (err error) { _, err = rw.closingWriter.Write([]byte{0}) return } + +func (rw *RWCancel) Close() { + rw.closingReader.Close() + rw.closingWriter.Close() +} diff --git a/vendor/golang.zx2c4.com/wireguard/rwcancel/rwcancel_stub.go b/vendor/golang.zx2c4.com/wireguard/rwcancel/rwcancel_stub.go new file mode 100644 index 0000000000..182940b32e --- /dev/null +++ b/vendor/golang.zx2c4.com/wireguard/rwcancel/rwcancel_stub.go @@ -0,0 +1,9 @@ +//go:build windows || js + +// SPDX-License-Identifier: MIT + +package rwcancel + +type RWCancel struct{} + +func (*RWCancel) Cancel() {} diff --git a/vendor/golang.zx2c4.com/wireguard/rwcancel/select_default.go b/vendor/golang.zx2c4.com/wireguard/rwcancel/select_default.go deleted file mode 100644 index dd23cdaa9f..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/rwcancel/select_default.go +++ /dev/null @@ -1,14 +0,0 @@ -// +build !linux - -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2017-2019 WireGuard LLC. All Rights Reserved. - */ - -package rwcancel - -import "golang.org/x/sys/unix" - -func unixSelect(nfd int, r *unix.FdSet, w *unix.FdSet, e *unix.FdSet, timeout *unix.Timeval) error { - return unix.Select(nfd, r, w, e, timeout) -} diff --git a/vendor/golang.zx2c4.com/wireguard/rwcancel/select_linux.go b/vendor/golang.zx2c4.com/wireguard/rwcancel/select_linux.go deleted file mode 100644 index 1a72e0ade1..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/rwcancel/select_linux.go +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2017-2019 WireGuard LLC. All Rights Reserved. - */ - -package rwcancel - -import "golang.org/x/sys/unix" - -func unixSelect(nfd int, r *unix.FdSet, w *unix.FdSet, e *unix.FdSet, timeout *unix.Timeval) (err error) { - _, err = unix.Select(nfd, r, w, e, timeout) - return -} diff --git a/vendor/golang.zx2c4.com/wireguard/tun/operateonfd.go b/vendor/golang.zx2c4.com/wireguard/tun/operateonfd.go index 31747a2482..f1beb6d6a5 100644 --- a/vendor/golang.zx2c4.com/wireguard/tun/operateonfd.go +++ b/vendor/golang.zx2c4.com/wireguard/tun/operateonfd.go @@ -1,8 +1,8 @@ -// +build !windows +//go:build darwin || freebsd /* SPDX-License-Identifier: MIT * - * Copyright (C) 2017-2019 WireGuard LLC. All Rights Reserved. + * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved. */ package tun diff --git a/vendor/golang.zx2c4.com/wireguard/tun/tun.go b/vendor/golang.zx2c4.com/wireguard/tun/tun.go index 5395bdbcd7..01051b938e 100644 --- a/vendor/golang.zx2c4.com/wireguard/tun/tun.go +++ b/vendor/golang.zx2c4.com/wireguard/tun/tun.go @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: MIT * - * Copyright (C) 2017-2019 WireGuard LLC. All Rights Reserved. + * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved. */ package tun @@ -24,6 +24,6 @@ type Device interface { Flush() error // flush all previous writes to the device MTU() (int, error) // returns the MTU of the device Name() (string, error) // fetches and returns the current name - Events() chan Event // returns a constant channel of events related to the device + Events() <-chan Event // returns a constant channel of events related to the device Close() error // stops the device and closes the event channel } diff --git a/vendor/golang.zx2c4.com/wireguard/tun/tun_darwin.go b/vendor/golang.zx2c4.com/wireguard/tun/tun_darwin.go index f19a7df981..7411a69463 100644 --- a/vendor/golang.zx2c4.com/wireguard/tun/tun_darwin.go +++ b/vendor/golang.zx2c4.com/wireguard/tun/tun_darwin.go @@ -1,15 +1,16 @@ /* SPDX-License-Identifier: MIT * - * Copyright (C) 2017-2019 WireGuard LLC. All Rights Reserved. + * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved. */ package tun import ( + "errors" "fmt" - "io/ioutil" "net" "os" + "sync" "syscall" "time" "unsafe" @@ -20,39 +21,21 @@ import ( const utunControlName = "com.apple.net.utun_control" -// _CTLIOCGINFO value derived from /usr/include/sys/{kern_control,ioccom}.h -const _CTLIOCGINFO = (0x40000000 | 0x80000000) | ((100 & 0x1fff) << 16) | uint32(byte('N'))<<8 | 3 - -// sockaddr_ctl specifeid in /usr/include/sys/kern_control.h -type sockaddrCtl struct { - scLen uint8 - scFamily uint8 - ssSysaddr uint16 - scID uint32 - scUnit uint32 - scReserved [5]uint32 -} - type NativeTun struct { name string tunFile *os.File events chan Event errors chan error routeSocket int + closeOnce sync.Once } -var sockaddrCtlSize uintptr = 32 - func retryInterfaceByIndex(index int) (iface *net.Interface, err error) { for i := 0; i < 20; i++ { iface, err = net.InterfaceByIndex(index) - if err != nil { - if opErr, ok := err.(*net.OpError); ok { - if syscallErr, ok := opErr.Err.(*os.SyscallError); ok && syscallErr.Err == syscall.ENOMEM { - time.Sleep(time.Duration(i) * time.Second / 3) - continue - } - } + if err != nil && errors.Is(err, syscall.ENOMEM) { + time.Sleep(time.Duration(i) * time.Second / 3) + continue } return iface, err } @@ -124,53 +107,33 @@ func CreateTUN(name string, mtu int) (Device, error) { } } - fd, err := unix.Socket(unix.AF_SYSTEM, unix.SOCK_DGRAM, 2) - + fd, err := socketCloexec(unix.AF_SYSTEM, unix.SOCK_DGRAM, 2) if err != nil { return nil, err } - var ctlInfo = &struct { - ctlID uint32 - ctlName [96]byte - }{} - - copy(ctlInfo.ctlName[:], []byte(utunControlName)) - - _, _, errno := unix.Syscall( - unix.SYS_IOCTL, - uintptr(fd), - uintptr(_CTLIOCGINFO), - uintptr(unsafe.Pointer(ctlInfo)), - ) - - if errno != 0 { - return nil, fmt.Errorf("_CTLIOCGINFO: %v", errno) + ctlInfo := &unix.CtlInfo{} + copy(ctlInfo.Name[:], []byte(utunControlName)) + err = unix.IoctlCtlInfo(fd, ctlInfo) + if err != nil { + unix.Close(fd) + return nil, fmt.Errorf("IoctlGetCtlInfo: %w", err) } - sc := sockaddrCtl{ - scLen: uint8(sockaddrCtlSize), - scFamily: unix.AF_SYSTEM, - ssSysaddr: 2, - scID: ctlInfo.ctlID, - scUnit: uint32(ifIndex) + 1, + sc := &unix.SockaddrCtl{ + ID: ctlInfo.Id, + Unit: uint32(ifIndex) + 1, } - scPointer := unsafe.Pointer(&sc) - - _, _, errno = unix.RawSyscall( - unix.SYS_CONNECT, - uintptr(fd), - uintptr(scPointer), - uintptr(sockaddrCtlSize), - ) - - if errno != 0 { - return nil, fmt.Errorf("SYS_CONNECT: %v", errno) + err = unix.Connect(fd, sc) + if err != nil { + unix.Close(fd) + return nil, err } - err = syscall.SetNonblock(fd, true) + err = unix.SetNonblock(fd, true) if err != nil { + unix.Close(fd) return nil, err } tun, err := CreateTUNFromFile(os.NewFile(uintptr(fd), ""), mtu) @@ -178,7 +141,7 @@ func CreateTUN(name string, mtu int) (Device, error) { if err == nil && name == "utun" { fname := os.Getenv("WG_TUN_NAME_FILE") if fname != "" { - ioutil.WriteFile(fname, []byte(tun.(*NativeTun).name+"\n"), 0400) + os.WriteFile(fname, []byte(tun.(*NativeTun).name+"\n"), 0o400) } } @@ -210,7 +173,7 @@ func CreateTUNFromFile(file *os.File, mtu int) (Device, error) { return nil, err } - tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC) + tun.routeSocket, err = socketCloexec(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC) if err != nil { tun.tunFile.Close() return nil, err @@ -230,27 +193,19 @@ func CreateTUNFromFile(file *os.File, mtu int) (Device, error) { } func (tun *NativeTun) Name() (string, error) { - var ifName struct { - name [16]byte - } - ifNameSize := uintptr(16) - - var errno syscall.Errno + var err error tun.operateOnFd(func(fd uintptr) { - _, _, errno = unix.Syscall6( - unix.SYS_GETSOCKOPT, - fd, + tun.name, err = unix.GetsockoptString( + int(fd), 2, /* #define SYSPROTO_CONTROL 2 */ 2, /* #define UTUN_OPT_IFNAME 2 */ - uintptr(unsafe.Pointer(&ifName)), - uintptr(unsafe.Pointer(&ifNameSize)), 0) + ) }) - if errno != 0 { - return "", fmt.Errorf("SYS_GETSOCKOPT: %v", errno) + if err != nil { + return "", fmt.Errorf("GetSockoptString: %w", err) } - tun.name = string(ifName.name[:ifNameSize-1]) return tun.name, nil } @@ -258,7 +213,7 @@ func (tun *NativeTun) File() *os.File { return tun.tunFile } -func (tun *NativeTun) Events() chan Event { +func (tun *NativeTun) Events() <-chan Event { return tun.events } @@ -277,7 +232,6 @@ func (tun *NativeTun) Read(buff []byte, offset int) (int, error) { } func (tun *NativeTun) Write(buff []byte, offset int) (int, error) { - // reserve space for header buff = buff[offset-4:] @@ -305,14 +259,16 @@ func (tun *NativeTun) Flush() error { } func (tun *NativeTun) Close() error { - var err2 error - err1 := tun.tunFile.Close() - if tun.routeSocket != -1 { - unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR) - err2 = unix.Close(tun.routeSocket) - } else if tun.events != nil { - close(tun.events) - } + var err1, err2 error + tun.closeOnce.Do(func() { + err1 = tun.tunFile.Close() + if tun.routeSocket != -1 { + unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR) + err2 = unix.Close(tun.routeSocket) + } else if tun.events != nil { + close(tun.events) + } + }) if err1 != nil { return err1 } @@ -320,71 +276,56 @@ func (tun *NativeTun) Close() error { } func (tun *NativeTun) setMTU(n int) error { - - // open datagram socket - - var fd int - - fd, err := unix.Socket( + fd, err := socketCloexec( unix.AF_INET, unix.SOCK_DGRAM, 0, ) - if err != nil { return err } defer unix.Close(fd) - // do ioctl call - - var ifr [32]byte - copy(ifr[:], tun.name) - *(*uint32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])) = uint32(n) - _, _, errno := unix.Syscall( - unix.SYS_IOCTL, - uintptr(fd), - uintptr(unix.SIOCSIFMTU), - uintptr(unsafe.Pointer(&ifr[0])), - ) - - if errno != 0 { - return fmt.Errorf("failed to set MTU on %s", tun.name) + var ifr unix.IfreqMTU + copy(ifr.Name[:], tun.name) + ifr.MTU = int32(n) + err = unix.IoctlSetIfreqMTU(fd, &ifr) + if err != nil { + return fmt.Errorf("failed to set MTU on %s: %w", tun.name, err) } return nil } func (tun *NativeTun) MTU() (int, error) { - - // open datagram socket - - fd, err := unix.Socket( + fd, err := socketCloexec( unix.AF_INET, unix.SOCK_DGRAM, 0, ) - if err != nil { return 0, err } defer unix.Close(fd) - // do ioctl call - - var ifr [64]byte - copy(ifr[:], tun.name) - _, _, errno := unix.Syscall( - unix.SYS_IOCTL, - uintptr(fd), - uintptr(unix.SIOCGIFMTU), - uintptr(unsafe.Pointer(&ifr[0])), - ) - if errno != 0 { - return 0, fmt.Errorf("failed to get MTU on %s", tun.name) + ifr, err := unix.IoctlGetIfreqMTU(fd, tun.name) + if err != nil { + return 0, fmt.Errorf("failed to get MTU on %s: %w", tun.name, err) } - return int(*(*int32)(unsafe.Pointer(&ifr[16]))), nil + return int(ifr.MTU), nil +} + +func socketCloexec(family, sotype, proto int) (fd int, err error) { + // See go/src/net/sys_cloexec.go for background. + syscall.ForkLock.RLock() + defer syscall.ForkLock.RUnlock() + + fd, err = unix.Socket(family, sotype, proto) + if err == nil { + unix.CloseOnExec(fd) + } + return } diff --git a/vendor/golang.zx2c4.com/wireguard/tun/tun_freebsd.go b/vendor/golang.zx2c4.com/wireguard/tun/tun_freebsd.go index 6cf93136f8..42431aa3ee 100644 --- a/vendor/golang.zx2c4.com/wireguard/tun/tun_freebsd.go +++ b/vendor/golang.zx2c4.com/wireguard/tun/tun_freebsd.go @@ -1,66 +1,57 @@ /* SPDX-License-Identifier: MIT * - * Copyright (C) 2017-2019 WireGuard LLC. All Rights Reserved. + * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved. */ package tun import ( - "bytes" "errors" "fmt" + "io" "net" "os" + "sync" "syscall" "unsafe" - "golang.org/x/net/ipv6" "golang.org/x/sys/unix" ) -// _TUNSIFHEAD, value derived from sys/net/{if_tun,ioccom}.h -// const _TUNSIFHEAD = ((0x80000000) | (((4) & ((1 << 13) - 1) ) << 16) | (uint32(byte('t')) << 8) | (96)) const ( _TUNSIFHEAD = 0x80047460 _TUNSIFMODE = 0x8004745e + _TUNGIFNAME = 0x4020745d _TUNSIFPID = 0x2000745f -) -// TODO: move into x/sys/unix -const ( - SIOCGIFINFO_IN6 = 0xc048696c - SIOCSIFINFO_IN6 = 0xc048696d - ND6_IFF_AUTO_LINKLOCAL = 0x20 - ND6_IFF_NO_DAD = 0x100 + _SIOCGIFINFO_IN6 = 0xc048696c + _SIOCSIFINFO_IN6 = 0xc048696d + _ND6_IFF_AUTO_LINKLOCAL = 0x20 + _ND6_IFF_NO_DAD = 0x100 ) -// Iface status string max len -const _IFSTATMAX = 800 - -const SIZEOF_UINTPTR = 4 << (^uintptr(0) >> 32 & 1) +// Iface requests with just the name +type ifreqName struct { + Name [unix.IFNAMSIZ]byte + _ [16]byte +} -// structure for iface requests with a pointer -type ifreq_ptr struct { +// Iface requests with a pointer +type ifreqPtr struct { Name [unix.IFNAMSIZ]byte Data uintptr - Pad0 [16 - SIZEOF_UINTPTR]byte + _ [16 - unsafe.Sizeof(uintptr(0))]byte } -// Structure for iface mtu get/set ioctls -type ifreq_mtu struct { +// Iface requests with MTU +type ifreqMtu struct { Name [unix.IFNAMSIZ]byte MTU uint32 - Pad0 [12]byte -} - -// Structure for interface status request ioctl -type ifstat struct { - IfsName [unix.IFNAMSIZ]byte - Ascii [_IFSTATMAX]byte + _ [12]byte } -// Structures for nd6 flag manipulation -type in6_ndireq struct { +// ND6 flag manipulation +type nd6Req struct { Name [unix.IFNAMSIZ]byte Linkmtu uint32 Maxmtu uint32 @@ -82,6 +73,7 @@ type NativeTun struct { events chan Event errors chan error routeSocket int + closeOnce sync.Once } func (tun *NativeTun) routineRouteListener(tunIfindex int) { @@ -97,7 +89,7 @@ func (tun *NativeTun) routineRouteListener(tunIfindex int) { retry: n, err := unix.Read(tun.routeSocket, data) if err != nil { - if errno, ok := err.(syscall.Errno); ok && errno == syscall.EINTR { + if errors.Is(err, syscall.EINTR) { goto retry } tun.errors <- err @@ -141,91 +133,17 @@ func (tun *NativeTun) routineRouteListener(tunIfindex int) { } func tunName(fd uintptr) (string, error) { - //Terrible hack to make up for freebsd not having a TUNGIFNAME - - //First, make sure the tun pid matches this proc's pid - _, _, errno := unix.Syscall( - unix.SYS_IOCTL, - uintptr(fd), - uintptr(_TUNSIFPID), - uintptr(0), - ) - - if errno != 0 { - return "", fmt.Errorf("failed to set tun device PID: %s", errno.Error()) - } - - // Open iface control socket - - confd, err := unix.Socket( - unix.AF_INET, - unix.SOCK_DGRAM, - 0, - ) - - if err != nil { + var ifreq ifreqName + _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, _TUNGIFNAME, uintptr(unsafe.Pointer(&ifreq))) + if err != 0 { return "", err } - - defer unix.Close(confd) - - procPid := os.Getpid() - - //Try to find interface with matching PID - for i := 1; ; i++ { - iface, _ := net.InterfaceByIndex(i) - if err != nil || iface == nil { - break - } - - // Structs for getting data in and out of SIOCGIFSTATUS ioctl - var ifstatus ifstat - copy(ifstatus.IfsName[:], iface.Name) - - // Make the syscall to get the status string - _, _, errno := unix.Syscall( - unix.SYS_IOCTL, - uintptr(confd), - uintptr(unix.SIOCGIFSTATUS), - uintptr(unsafe.Pointer(&ifstatus)), - ) - - if errno != 0 { - continue - } - - nullStr := ifstatus.Ascii[:] - i := bytes.IndexByte(nullStr, 0) - if i < 1 { - continue - } - statStr := string(nullStr[:i]) - var pidNum int = 0 - - // Finally get the owning PID - // Format string taken from sys/net/if_tun.c - _, err := fmt.Sscanf(statStr, "\tOpened by PID %d\n", &pidNum) - if err != nil { - continue - } - - if pidNum == procPid { - return iface.Name, nil - } - } - - return "", nil + return unix.ByteSliceToString(ifreq.Name[:]), nil } // Destroy a named system interface func tunDestroy(name string) error { - // Open control socket. - var fd int - fd, err := unix.Socket( - unix.AF_INET, - unix.SOCK_DGRAM, - 0, - ) + fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0) if err != nil { return err } @@ -233,14 +151,9 @@ func tunDestroy(name string) error { var ifr [32]byte copy(ifr[:], name) - _, _, errno := unix.Syscall( - unix.SYS_IOCTL, - uintptr(fd), - uintptr(unix.SIOCIFDESTROY), - uintptr(unsafe.Pointer(&ifr[0])), - ) + _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), uintptr(unix.SIOCIFDESTROY), uintptr(unsafe.Pointer(&ifr[0]))) if errno != 0 { - return fmt.Errorf("failed to destroy interface %s: %s", name, errno.Error()) + return fmt.Errorf("failed to destroy interface %s: %w", name, errno) } return nil @@ -257,7 +170,7 @@ func CreateTUN(name string, mtu int) (Device, error) { return nil, fmt.Errorf("interface %s already exists", name) } - tunFile, err := os.OpenFile("/dev/tun", unix.O_RDWR, 0) + tunFile, err := os.OpenFile("/dev/tun", unix.O_RDWR|unix.O_CLOEXEC, 0) if err != nil { return nil, err } @@ -276,103 +189,94 @@ func CreateTUN(name string, mtu int) (Device, error) { ifheadmode := 1 var errno syscall.Errno tun.operateOnFd(func(fd uintptr) { - _, _, errno = unix.Syscall( - unix.SYS_IOCTL, - fd, - uintptr(_TUNSIFHEAD), - uintptr(unsafe.Pointer(&ifheadmode)), - ) + _, _, errno = unix.Syscall(unix.SYS_IOCTL, fd, _TUNSIFHEAD, uintptr(unsafe.Pointer(&ifheadmode))) }) if errno != 0 { tunFile.Close() tunDestroy(assignedName) - return nil, fmt.Errorf("Unable to put into IFHEAD mode: %v", errno) + return nil, fmt.Errorf("unable to put into IFHEAD mode: %w", errno) } - // Open control sockets - confd, err := unix.Socket( - unix.AF_INET, - unix.SOCK_DGRAM, - 0, - ) - if err != nil { + // Get out of PTP mode. + ifflags := syscall.IFF_BROADCAST | syscall.IFF_MULTICAST + tun.operateOnFd(func(fd uintptr) { + _, _, errno = unix.Syscall(unix.SYS_IOCTL, fd, uintptr(_TUNSIFMODE), uintptr(unsafe.Pointer(&ifflags))) + }) + + if errno != 0 { tunFile.Close() tunDestroy(assignedName) - return nil, err + return nil, fmt.Errorf("unable to put into IFF_BROADCAST mode: %w", errno) } - defer unix.Close(confd) - confd6, err := unix.Socket( - unix.AF_INET6, - unix.SOCK_DGRAM, - 0, - ) + + // Disable link-local v6, not just because WireGuard doesn't do that anyway, but + // also because there are serious races with attaching and detaching LLv6 addresses + // in relation to interface lifetime within the FreeBSD kernel. + confd6, err := unix.Socket(unix.AF_INET6, unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0) if err != nil { tunFile.Close() tunDestroy(assignedName) return nil, err } defer unix.Close(confd6) - - // Disable link-local v6, not just because WireGuard doesn't do that anyway, but - // also because there are serious races with attaching and detaching LLv6 addresses - // in relation to interface lifetime within the FreeBSD kernel. - var ndireq in6_ndireq + var ndireq nd6Req copy(ndireq.Name[:], assignedName) - _, _, errno = unix.Syscall( - unix.SYS_IOCTL, - uintptr(confd6), - uintptr(SIOCGIFINFO_IN6), - uintptr(unsafe.Pointer(&ndireq)), - ) + _, _, errno = unix.Syscall(unix.SYS_IOCTL, uintptr(confd6), uintptr(_SIOCGIFINFO_IN6), uintptr(unsafe.Pointer(&ndireq))) if errno != 0 { tunFile.Close() tunDestroy(assignedName) - return nil, fmt.Errorf("Unable to get nd6 flags for %s: %v", assignedName, errno) + return nil, fmt.Errorf("unable to get nd6 flags for %s: %w", assignedName, errno) } - ndireq.Flags = ndireq.Flags &^ ND6_IFF_AUTO_LINKLOCAL - ndireq.Flags = ndireq.Flags | ND6_IFF_NO_DAD - _, _, errno = unix.Syscall( - unix.SYS_IOCTL, - uintptr(confd6), - uintptr(SIOCSIFINFO_IN6), - uintptr(unsafe.Pointer(&ndireq)), - ) + ndireq.Flags = ndireq.Flags &^ _ND6_IFF_AUTO_LINKLOCAL + ndireq.Flags = ndireq.Flags | _ND6_IFF_NO_DAD + _, _, errno = unix.Syscall(unix.SYS_IOCTL, uintptr(confd6), uintptr(_SIOCSIFINFO_IN6), uintptr(unsafe.Pointer(&ndireq))) if errno != 0 { tunFile.Close() tunDestroy(assignedName) - return nil, fmt.Errorf("Unable to set nd6 flags for %s: %v", assignedName, errno) + return nil, fmt.Errorf("unable to set nd6 flags for %s: %w", assignedName, errno) } - // Rename the interface - var newnp [unix.IFNAMSIZ]byte - copy(newnp[:], name) - var ifr ifreq_ptr - copy(ifr.Name[:], assignedName) - ifr.Data = uintptr(unsafe.Pointer(&newnp[0])) - _, _, errno = unix.Syscall( - unix.SYS_IOCTL, - uintptr(confd), - uintptr(unix.SIOCSIFNAME), - uintptr(unsafe.Pointer(&ifr)), - ) - if errno != 0 { - tunFile.Close() - tunDestroy(assignedName) - return nil, fmt.Errorf("Failed to rename %s to %s: %v", assignedName, name, errno) + if name != "" { + confd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0) + if err != nil { + tunFile.Close() + tunDestroy(assignedName) + return nil, err + } + defer unix.Close(confd) + var newnp [unix.IFNAMSIZ]byte + copy(newnp[:], name) + var ifr ifreqPtr + copy(ifr.Name[:], assignedName) + ifr.Data = uintptr(unsafe.Pointer(&newnp[0])) + _, _, errno = unix.Syscall(unix.SYS_IOCTL, uintptr(confd), uintptr(unix.SIOCSIFNAME), uintptr(unsafe.Pointer(&ifr))) + if errno != 0 { + tunFile.Close() + tunDestroy(assignedName) + return nil, fmt.Errorf("Failed to rename %s to %s: %w", assignedName, name, errno) + } } return CreateTUNFromFile(tunFile, mtu) } func CreateTUNFromFile(file *os.File, mtu int) (Device, error) { - tun := &NativeTun{ tunFile: file, events: make(chan Event, 10), errors: make(chan error, 1), } + var errno syscall.Errno + tun.operateOnFd(func(fd uintptr) { + _, _, errno = unix.Syscall(unix.SYS_IOCTL, fd, _TUNSIFPID, uintptr(0)) + }) + if errno != 0 { + tun.tunFile.Close() + return nil, fmt.Errorf("unable to become controlling TUN process: %w", errno) + } + name, err := tun.Name() if err != nil { tun.tunFile.Close() @@ -391,7 +295,7 @@ func CreateTUNFromFile(file *os.File, mtu int) (Device, error) { return nil, err } - tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC) + tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW|unix.SOCK_CLOEXEC, unix.AF_UNSPEC) if err != nil { tun.tunFile.Close() return nil, err @@ -425,7 +329,7 @@ func (tun *NativeTun) File() *os.File { return tun.tunFile } -func (tun *NativeTun) Events() chan Event { +func (tun *NativeTun) Events() <-chan Event { return tun.events } @@ -443,27 +347,26 @@ func (tun *NativeTun) Read(buff []byte, offset int) (int, error) { } } -func (tun *NativeTun) Write(buff []byte, offset int) (int, error) { - - // reserve space for header - - buff = buff[offset-4:] - - // add packet information header - - buff[0] = 0x00 - buff[1] = 0x00 - buff[2] = 0x00 - - if buff[4]>>4 == ipv6.Version { - buff[3] = unix.AF_INET6 - } else { - buff[3] = unix.AF_INET +func (tun *NativeTun) Write(buf []byte, offset int) (int, error) { + if offset < 4 { + return 0, io.ErrShortBuffer } - - // write - - return tun.tunFile.Write(buff) + buf = buf[offset-4:] + if len(buf) < 5 { + return 0, io.ErrShortBuffer + } + buf[0] = 0x00 + buf[1] = 0x00 + buf[2] = 0x00 + switch buf[4] >> 4 { + case 4: + buf[3] = unix.AF_INET + case 6: + buf[3] = unix.AF_INET6 + default: + return 0, unix.EAFNOSUPPORT + } + return tun.tunFile.Write(buf) } func (tun *NativeTun) Flush() error { @@ -472,16 +375,18 @@ func (tun *NativeTun) Flush() error { } func (tun *NativeTun) Close() error { - var err3 error - err1 := tun.tunFile.Close() - err2 := tunDestroy(tun.name) - if tun.routeSocket != -1 { - unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR) - err3 = unix.Close(tun.routeSocket) - tun.routeSocket = -1 - } else if tun.events != nil { - close(tun.events) - } + var err1, err2, err3 error + tun.closeOnce.Do(func() { + err1 = tun.tunFile.Close() + err2 = tunDestroy(tun.name) + if tun.routeSocket != -1 { + unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR) + err3 = unix.Close(tun.routeSocket) + tun.routeSocket = -1 + } else if tun.events != nil { + close(tun.events) + } + }) if err1 != nil { return err1 } @@ -492,70 +397,34 @@ func (tun *NativeTun) Close() error { } func (tun *NativeTun) setMTU(n int) error { - // open datagram socket - - var fd int - - fd, err := unix.Socket( - unix.AF_INET, - unix.SOCK_DGRAM, - 0, - ) - + fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0) if err != nil { return err } - defer unix.Close(fd) - // do ioctl call - - var ifr ifreq_mtu + var ifr ifreqMtu copy(ifr.Name[:], tun.name) ifr.MTU = uint32(n) - - _, _, errno := unix.Syscall( - unix.SYS_IOCTL, - uintptr(fd), - uintptr(unix.SIOCSIFMTU), - uintptr(unsafe.Pointer(&ifr)), - ) - + _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), uintptr(unix.SIOCSIFMTU), uintptr(unsafe.Pointer(&ifr))) if errno != 0 { - return fmt.Errorf("failed to set MTU on %s", tun.name) + return fmt.Errorf("failed to set MTU on %s: %w", tun.name, errno) } - return nil } func (tun *NativeTun) MTU() (int, error) { - // open datagram socket - - fd, err := unix.Socket( - unix.AF_INET, - unix.SOCK_DGRAM, - 0, - ) - + fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0) if err != nil { return 0, err } - defer unix.Close(fd) - // do ioctl call - var ifr ifreq_mtu + var ifr ifreqMtu copy(ifr.Name[:], tun.name) - - _, _, errno := unix.Syscall( - unix.SYS_IOCTL, - uintptr(fd), - uintptr(unix.SIOCGIFMTU), - uintptr(unsafe.Pointer(&ifr)), - ) + _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), uintptr(unix.SIOCGIFMTU), uintptr(unsafe.Pointer(&ifr))) if errno != 0 { - return 0, fmt.Errorf("failed to get MTU on %s", tun.name) + return 0, fmt.Errorf("failed to get MTU on %s: %w", tun.name, errno) } - return int(*(*int32)(unsafe.Pointer(&ifr.MTU))), nil } diff --git a/vendor/golang.zx2c4.com/wireguard/tun/tun_linux.go b/vendor/golang.zx2c4.com/wireguard/tun/tun_linux.go index 7ab0623146..25dbc0749b 100644 --- a/vendor/golang.zx2c4.com/wireguard/tun/tun_linux.go +++ b/vendor/golang.zx2c4.com/wireguard/tun/tun_linux.go @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: MIT * - * Copyright (C) 2017-2019 WireGuard LLC. All Rights Reserved. + * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved. */ package tun @@ -9,10 +9,8 @@ package tun */ import ( - "bytes" "errors" "fmt" - "net" "os" "sync" "syscall" @@ -21,6 +19,7 @@ import ( "golang.org/x/net/ipv6" "golang.org/x/sys/unix" + "golang.zx2c4.com/wireguard/rwcancel" ) @@ -32,7 +31,6 @@ const ( type NativeTun struct { tunFile *os.File index int32 // if index - name string // name of interface errors chan error // async error handling events chan Event // device related events nopi bool // the device was passed IFF_NO_PI @@ -40,6 +38,12 @@ type NativeTun struct { netlinkCancel *rwcancel.RWCancel hackListenerClosed sync.Mutex statusListenersShutdown chan struct{} + + closeOnce sync.Once + + nameOnce sync.Once // guards calling initNameCache, which sets following fields + nameCache string // name of interface + nameErr error } func (tun *NativeTun) File() *os.File { @@ -51,6 +55,11 @@ func (tun *NativeTun) routineHackListener() { /* This is needed for the detection to work across network namespaces * If you are reading this and know a better method, please get in touch. */ + last := 0 + const ( + up = 1 + down = 2 + ) for { sysconn, err := tun.tunFile.SyscallConn() if err != nil { @@ -64,14 +73,25 @@ func (tun *NativeTun) routineHackListener() { } switch err { case unix.EINVAL: - tun.events <- EventUp + if last != up { + // If the tunnel is up, it reports that write() is + // allowed but we provided invalid data. + tun.events <- EventUp + last = up + } case unix.EIO: - tun.events <- EventDown + if last != down { + // If the tunnel is down, it reports that no I/O + // is possible, without checking our provided data. + tun.events <- EventDown + last = down + } default: return } select { case <-time.After(time.Second): + // nothing case <-tun.statusListenersShutdown: return } @@ -79,7 +99,7 @@ func (tun *NativeTun) routineHackListener() { } func createNetlinkSocket() (int, error) { - sock, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW, unix.NETLINK_ROUTE) + sock, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW|unix.SOCK_CLOEXEC, unix.NETLINK_ROUTE) if err != nil { return -1, err } @@ -99,10 +119,10 @@ func (tun *NativeTun) routineNetlinkListener() { unix.Close(tun.netlinkSock) tun.hackListenerClosed.Lock() close(tun.events) + tun.netlinkCancel.Close() }() for msg := make([]byte, 1<<16); ; { - var err error var msgn int for { @@ -111,12 +131,12 @@ func (tun *NativeTun) routineNetlinkListener() { break } if !tun.netlinkCancel.ReadyRead() { - tun.errors <- fmt.Errorf("netlink socket closed: %s", err.Error()) + tun.errors <- fmt.Errorf("netlink socket closed: %w", err) return } } if err != nil { - tun.errors <- fmt.Errorf("failed to receive netlink message: %s", err.Error()) + tun.errors <- fmt.Errorf("failed to receive netlink message: %w", err) return } @@ -126,6 +146,7 @@ func (tun *NativeTun) routineNetlinkListener() { default: } + wasEverUp := false for remain := msg[:msgn]; len(remain) >= unix.SizeofNlMsghdr; { hdr := *(*unix.NlMsghdr)(unsafe.Pointer(&remain[0])) @@ -149,10 +170,16 @@ func (tun *NativeTun) routineNetlinkListener() { if info.Flags&unix.IFF_RUNNING != 0 { tun.events <- EventUp + wasEverUp = true } if info.Flags&unix.IFF_RUNNING == 0 { - tun.events <- EventDown + // Don't emit EventDown before we've ever emitted EventUp. + // This avoids a startup race with HackListener, which + // might detect Up before we have finished reporting Down. + if wasEverUp { + tun.events <- EventDown + } } tun.events <- EventMTUUpdate @@ -164,15 +191,10 @@ func (tun *NativeTun) routineNetlinkListener() { } } -func (tun *NativeTun) isUp() (bool, error) { - inter, err := net.InterfaceByName(tun.name) - return inter.Flags&net.FlagUp != 0, err -} - func getIFIndex(name string) (int32, error) { fd, err := unix.Socket( unix.AF_INET, - unix.SOCK_DGRAM, + unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0, ) if err != nil { @@ -198,13 +220,17 @@ func getIFIndex(name string) (int32, error) { } func (tun *NativeTun) setMTU(n int) error { + name, err := tun.Name() + if err != nil { + return err + } + // open datagram socket fd, err := unix.Socket( unix.AF_INET, - unix.SOCK_DGRAM, + unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0, ) - if err != nil { return err } @@ -212,9 +238,8 @@ func (tun *NativeTun) setMTU(n int) error { defer unix.Close(fd) // do ioctl call - var ifr [ifReqSize]byte - copy(ifr[:], tun.name) + copy(ifr[:], name) *(*uint32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])) = uint32(n) _, _, errno := unix.Syscall( unix.SYS_IOCTL, @@ -224,20 +249,24 @@ func (tun *NativeTun) setMTU(n int) error { ) if errno != 0 { - return errors.New("failed to set MTU of TUN device") + return fmt.Errorf("failed to set MTU of TUN device: %w", errno) } return nil } func (tun *NativeTun) MTU() (int, error) { + name, err := tun.Name() + if err != nil { + return 0, err + } + // open datagram socket fd, err := unix.Socket( unix.AF_INET, - unix.SOCK_DGRAM, + unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0, ) - if err != nil { return 0, err } @@ -247,7 +276,7 @@ func (tun *NativeTun) MTU() (int, error) { // do ioctl call var ifr [ifReqSize]byte - copy(ifr[:], tun.name) + copy(ifr[:], name) _, _, errno := unix.Syscall( unix.SYS_IOCTL, uintptr(fd), @@ -255,13 +284,22 @@ func (tun *NativeTun) MTU() (int, error) { uintptr(unsafe.Pointer(&ifr[0])), ) if errno != 0 { - return 0, errors.New("failed to get MTU of TUN device: " + errno.Error()) + return 0, fmt.Errorf("failed to get MTU of TUN device: %w", errno) } return int(*(*int32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ]))), nil } func (tun *NativeTun) Name() (string, error) { + tun.nameOnce.Do(tun.initNameCache) + return tun.nameCache, tun.nameErr +} + +func (tun *NativeTun) initNameCache() { + tun.nameCache, tun.nameErr = tun.nameSlow() +} + +func (tun *NativeTun) nameSlow() (string, error) { sysconn, err := tun.tunFile.SyscallConn() if err != nil { return "", err @@ -277,46 +315,38 @@ func (tun *NativeTun) Name() (string, error) { ) }) if err != nil { - return "", errors.New("failed to get name of TUN device: " + err.Error()) + return "", fmt.Errorf("failed to get name of TUN device: %w", err) } if errno != 0 { - return "", errors.New("failed to get name of TUN device: " + errno.Error()) + return "", fmt.Errorf("failed to get name of TUN device: %w", errno) } - nullStr := ifr[:] - i := bytes.IndexByte(nullStr, 0) - if i != -1 { - nullStr = nullStr[:i] - } - tun.name = string(nullStr) - return tun.name, nil + return unix.ByteSliceToString(ifr[:]), nil } -func (tun *NativeTun) Write(buff []byte, offset int) (int, error) { - +func (tun *NativeTun) Write(buf []byte, offset int) (int, error) { if tun.nopi { - buff = buff[offset:] + buf = buf[offset:] } else { // reserve space for header - - buff = buff[offset-4:] + buf = buf[offset-4:] // add packet information header - - buff[0] = 0x00 - buff[1] = 0x00 - - if buff[4]>>4 == ipv6.Version { - buff[2] = 0x86 - buff[3] = 0xdd + buf[0] = 0x00 + buf[1] = 0x00 + if buf[4]>>4 == ipv6.Version { + buf[2] = 0x86 + buf[3] = 0xdd } else { - buff[2] = 0x08 - buff[3] = 0x00 + buf[2] = 0x08 + buf[3] = 0x00 } } - // write - - return tun.tunFile.Write(buff) + n, err := tun.tunFile.Write(buf) + if errors.Is(err, syscall.EBADFD) { + err = os.ErrClosed + } + return n, err } func (tun *NativeTun) Flush() error { @@ -324,40 +354,45 @@ func (tun *NativeTun) Flush() error { return nil } -func (tun *NativeTun) Read(buff []byte, offset int) (int, error) { +func (tun *NativeTun) Read(buf []byte, offset int) (n int, err error) { select { - case err := <-tun.errors: - return 0, err + case err = <-tun.errors: default: if tun.nopi { - return tun.tunFile.Read(buff[offset:]) + n, err = tun.tunFile.Read(buf[offset:]) } else { - buff := buff[offset-4:] - n, err := tun.tunFile.Read(buff[:]) + buff := buf[offset-4:] + n, err = tun.tunFile.Read(buff[:]) + if errors.Is(err, syscall.EBADFD) { + err = os.ErrClosed + } if n < 4 { - return 0, err + n = 0 + } else { + n -= 4 } - return n - 4, err } } + return } -func (tun *NativeTun) Events() chan Event { +func (tun *NativeTun) Events() <-chan Event { return tun.events } func (tun *NativeTun) Close() error { - var err1 error - if tun.statusListenersShutdown != nil { - close(tun.statusListenersShutdown) - if tun.netlinkCancel != nil { - err1 = tun.netlinkCancel.Cancel() + var err1, err2 error + tun.closeOnce.Do(func() { + if tun.statusListenersShutdown != nil { + close(tun.statusListenersShutdown) + if tun.netlinkCancel != nil { + err1 = tun.netlinkCancel.Cancel() + } + } else if tun.events != nil { + close(tun.events) } - } else if tun.events != nil { - close(tun.events) - } - err2 := tun.tunFile.Close() - + err2 = tun.tunFile.Close() + }) if err1 != nil { return err1 } @@ -365,8 +400,11 @@ func (tun *NativeTun) Close() error { } func CreateTUN(name string, mtu int) (Device, error) { - nfd, err := unix.Open(cloneDevicePath, os.O_RDWR, 0) + nfd, err := unix.Open(cloneDevicePath, unix.O_RDWR|unix.O_CLOEXEC, 0) if err != nil { + if os.IsNotExist(err) { + return nil, fmt.Errorf("CreateTUN(%q) failed; %s does not exist", name, cloneDevicePath) + } return nil, err } @@ -374,7 +412,8 @@ func CreateTUN(name string, mtu int) (Device, error) { var flags uint16 = unix.IFF_TUN // | unix.IFF_NO_PI (disabled for TUN status hack) nameBytes := []byte(name) if len(nameBytes) >= unix.IFNAMSIZ { - return nil, errors.New("interface name too long") + unix.Close(nfd) + return nil, fmt.Errorf("interface name too long: %w", unix.ENAMETOOLONG) } copy(ifr[:], nameBytes) *(*uint16)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])) = flags @@ -386,17 +425,19 @@ func CreateTUN(name string, mtu int) (Device, error) { uintptr(unsafe.Pointer(&ifr[0])), ) if errno != 0 { + unix.Close(nfd) return nil, errno } - err = unix.SetNonblock(nfd, true) - - // Note that the above -- open,ioctl,nonblock -- must happen prior to handing it to netpoll as below this line. - fd := os.NewFile(uintptr(nfd), cloneDevicePath) + err = unix.SetNonblock(nfd, true) if err != nil { + unix.Close(nfd) return nil, err } + // Note that the above -- open,ioctl,nonblock -- must happen prior to handing it to netpoll as below this line. + + fd := os.NewFile(uintptr(nfd), cloneDevicePath) return CreateTUNFromFile(fd, mtu) } @@ -408,16 +449,15 @@ func CreateTUNFromFile(file *os.File, mtu int) (Device, error) { statusListenersShutdown: make(chan struct{}), nopi: false, } - var err error - _, err = tun.Name() + name, err := tun.Name() if err != nil { return nil, err } // start event listener - tun.index, err = getIFIndex(tun.name) + tun.index, err = getIFIndex(name) if err != nil { return nil, err } diff --git a/vendor/golang.zx2c4.com/wireguard/tun/tun_openbsd.go b/vendor/golang.zx2c4.com/wireguard/tun/tun_openbsd.go index 44cedaa463..e7fd79c5b0 100644 --- a/vendor/golang.zx2c4.com/wireguard/tun/tun_openbsd.go +++ b/vendor/golang.zx2c4.com/wireguard/tun/tun_openbsd.go @@ -1,15 +1,16 @@ /* SPDX-License-Identifier: MIT * - * Copyright (C) 2017-2019 WireGuard LLC. All Rights Reserved. + * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved. */ package tun import ( + "errors" "fmt" - "io/ioutil" "net" "os" + "sync" "syscall" "unsafe" @@ -32,6 +33,7 @@ type NativeTun struct { events chan Event errors chan error routeSocket int + closeOnce sync.Once } func (tun *NativeTun) routineRouteListener(tunIfindex int) { @@ -99,16 +101,6 @@ func (tun *NativeTun) routineRouteListener(tunIfindex int) { } } -func errorIsEBUSY(err error) bool { - if pe, ok := err.(*os.PathError); ok { - err = pe.Err - } - if errno, ok := err.(syscall.Errno); ok && errno == syscall.EBUSY { - return true - } - return false -} - func CreateTUN(name string, mtu int) (Device, error) { ifIndex := -1 if name != "tun" { @@ -122,11 +114,11 @@ func CreateTUN(name string, mtu int) (Device, error) { var err error if ifIndex != -1 { - tunfile, err = os.OpenFile(fmt.Sprintf("/dev/tun%d", ifIndex), unix.O_RDWR, 0) + tunfile, err = os.OpenFile(fmt.Sprintf("/dev/tun%d", ifIndex), unix.O_RDWR|unix.O_CLOEXEC, 0) } else { - for ifIndex = 0; ifIndex < 256; ifIndex += 1 { - tunfile, err = os.OpenFile(fmt.Sprintf("/dev/tun%d", ifIndex), unix.O_RDWR, 0) - if err == nil || !errorIsEBUSY(err) { + for ifIndex = 0; ifIndex < 256; ifIndex++ { + tunfile, err = os.OpenFile(fmt.Sprintf("/dev/tun%d", ifIndex), unix.O_RDWR|unix.O_CLOEXEC, 0) + if err == nil || !errors.Is(err, syscall.EBUSY) { break } } @@ -141,7 +133,7 @@ func CreateTUN(name string, mtu int) (Device, error) { if err == nil && name == "tun" { fname := os.Getenv("WG_TUN_NAME_FILE") if fname != "" { - ioutil.WriteFile(fname, []byte(tun.(*NativeTun).name+"\n"), 0400) + os.WriteFile(fname, []byte(tun.(*NativeTun).name+"\n"), 0o400) } } @@ -173,7 +165,7 @@ func CreateTUNFromFile(file *os.File, mtu int) (Device, error) { return nil, err } - tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC) + tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW|unix.SOCK_CLOEXEC, unix.AF_UNSPEC) if err != nil { tun.tunFile.Close() return nil, err @@ -208,7 +200,7 @@ func (tun *NativeTun) File() *os.File { return tun.tunFile } -func (tun *NativeTun) Events() chan Event { +func (tun *NativeTun) Events() <-chan Event { return tun.events } @@ -227,7 +219,6 @@ func (tun *NativeTun) Read(buff []byte, offset int) (int, error) { } func (tun *NativeTun) Write(buff []byte, offset int) (int, error) { - // reserve space for header buff = buff[offset-4:] @@ -255,15 +246,17 @@ func (tun *NativeTun) Flush() error { } func (tun *NativeTun) Close() error { - var err2 error - err1 := tun.tunFile.Close() - if tun.routeSocket != -1 { - unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR) - err2 = unix.Close(tun.routeSocket) - tun.routeSocket = -1 - } else if tun.events != nil { - close(tun.events) - } + var err1, err2 error + tun.closeOnce.Do(func() { + err1 = tun.tunFile.Close() + if tun.routeSocket != -1 { + unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR) + err2 = unix.Close(tun.routeSocket) + tun.routeSocket = -1 + } else if tun.events != nil { + close(tun.events) + } + }) if err1 != nil { return err1 } @@ -277,10 +270,9 @@ func (tun *NativeTun) setMTU(n int) error { fd, err := unix.Socket( unix.AF_INET, - unix.SOCK_DGRAM, + unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0, ) - if err != nil { return err } @@ -312,10 +304,9 @@ func (tun *NativeTun) MTU() (int, error) { fd, err := unix.Socket( unix.AF_INET, - unix.SOCK_DGRAM, + unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0, ) - if err != nil { return 0, err } diff --git a/vendor/golang.zx2c4.com/wireguard/tun/tun_windows.go b/vendor/golang.zx2c4.com/wireguard/tun/tun_windows.go index b16dbb748f..d5abb14898 100644 --- a/vendor/golang.zx2c4.com/wireguard/tun/tun_windows.go +++ b/vendor/golang.zx2c4.com/wireguard/tun/tun_windows.go @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: MIT * - * Copyright (C) 2018-2019 WireGuard LLC. All Rights Reserved. + * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved. */ package tun @@ -12,11 +12,11 @@ import ( "sync" "sync/atomic" "time" - "unsafe" + _ "unsafe" "golang.org/x/sys/windows" - "golang.zx2c4.com/wireguard/tun/wintun" + "golang.zx2c4.com/wintun" ) const ( @@ -26,25 +26,30 @@ const ( ) type rateJuggler struct { - current uint64 - nextByteCount uint64 - nextStartTime int64 - changing int32 + current atomic.Uint64 + nextByteCount atomic.Uint64 + nextStartTime atomic.Int64 + changing atomic.Bool } type NativeTun struct { - wt *wintun.Interface + wt *wintun.Adapter + name string handle windows.Handle - close bool + rate rateJuggler + session wintun.Session + readWait windows.Handle events chan Event - errors chan error + running sync.WaitGroup + closeOnce sync.Once + close atomic.Bool forcedMTU int - rate rateJuggler - rings *wintun.RingDescriptor - writeLock sync.Mutex } -const WintunPool = wintun.Pool("WireGuard") +var ( + WintunTunnelType = "WireGuard" + WintunStaticRequestedGUID *windows.GUID +) //go:linkname procyield runtime.procyield func procyield(cycles uint32) @@ -52,34 +57,18 @@ func procyield(cycles uint32) //go:linkname nanotime runtime.nanotime func nanotime() int64 -// // CreateTUN creates a Wintun interface with the given name. Should a Wintun // interface with the same name exist, it is reused. -// func CreateTUN(ifname string, mtu int) (Device, error) { - return CreateTUNWithRequestedGUID(ifname, nil, mtu) + return CreateTUNWithRequestedGUID(ifname, WintunStaticRequestedGUID, mtu) } -// // CreateTUNWithRequestedGUID creates a Wintun interface with the given name and // a requested GUID. Should a Wintun interface with the same name exist, it is reused. -// func CreateTUNWithRequestedGUID(ifname string, requestedGUID *windows.GUID, mtu int) (Device, error) { - var err error - var wt *wintun.Interface - - // Does an interface with this name already exist? - wt, err = WintunPool.GetInterface(ifname) - if err == nil { - // If so, we delete it, in case it has weird residual configuration. - _, err = wt.DeleteInterface() - if err != nil { - return nil, fmt.Errorf("Error deleting already existing interface: %v", err) - } - } - wt, _, err = WintunPool.CreateInterface(ifname, requestedGUID) + wt, err := wintun.CreateAdapter(ifname, WintunTunnelType, requestedGUID) if err != nil { - return nil, fmt.Errorf("Error creating interface: %v", err) + return nil, fmt.Errorf("Error creating interface: %w", err) } forcedMTU := 1420 @@ -89,52 +78,46 @@ func CreateTUNWithRequestedGUID(ifname string, requestedGUID *windows.GUID, mtu tun := &NativeTun{ wt: wt, + name: ifname, handle: windows.InvalidHandle, events: make(chan Event, 10), - errors: make(chan error, 1), forcedMTU: forcedMTU, } - tun.rings, err = wintun.NewRingDescriptor() - if err != nil { - tun.Close() - return nil, fmt.Errorf("Error creating events: %v", err) - } - - tun.handle, err = tun.wt.Register(tun.rings) + tun.session, err = wt.StartSession(0x800000) // Ring capacity, 8 MiB if err != nil { - tun.Close() - return nil, fmt.Errorf("Error registering rings: %v", err) + tun.wt.Close() + close(tun.events) + return nil, fmt.Errorf("Error starting session: %w", err) } + tun.readWait = tun.session.ReadWaitEvent() return tun, nil } func (tun *NativeTun) Name() (string, error) { - return tun.wt.Name() + return tun.name, nil } func (tun *NativeTun) File() *os.File { return nil } -func (tun *NativeTun) Events() chan Event { +func (tun *NativeTun) Events() <-chan Event { return tun.events } func (tun *NativeTun) Close() error { - tun.close = true - if tun.rings.Send.TailMoved != 0 { - windows.SetEvent(tun.rings.Send.TailMoved) // wake the reader if it's sleeping - } - if tun.handle != windows.InvalidHandle { - windows.CloseHandle(tun.handle) - } - tun.rings.Close() var err error - if tun.wt != nil { - _, err = tun.wt.DeleteInterface() - } - close(tun.events) + tun.closeOnce.Do(func() { + tun.close.Store(true) + windows.SetEvent(tun.readWait) + tun.running.Wait() + tun.session.End() + if tun.wt != nil { + tun.wt.Close() + } + close(tun.events) + }) return err } @@ -144,68 +127,50 @@ func (tun *NativeTun) MTU() (int, error) { // TODO: This is a temporary hack. We really need to be monitoring the interface in real time and adapting to MTU changes. func (tun *NativeTun) ForceMTU(mtu int) { + update := tun.forcedMTU != mtu tun.forcedMTU = mtu + if update { + tun.events <- EventMTUUpdate + } } // Note: Read() and Write() assume the caller comes only from a single thread; there's no locking. func (tun *NativeTun) Read(buff []byte, offset int) (int, error) { + tun.running.Add(1) + defer tun.running.Done() retry: - select { - case err := <-tun.errors: - return 0, err - default: - } - if tun.close { + if tun.close.Load() { return 0, os.ErrClosed } - - buffHead := atomic.LoadUint32(&tun.rings.Send.Ring.Head) - if buffHead >= wintun.PacketCapacity { - return 0, os.ErrClosed - } - start := nanotime() - shouldSpin := atomic.LoadUint64(&tun.rate.current) >= spinloopRateThreshold && uint64(start-atomic.LoadInt64(&tun.rate.nextStartTime)) <= rateMeasurementGranularity*2 - var buffTail uint32 + shouldSpin := tun.rate.current.Load() >= spinloopRateThreshold && uint64(start-tun.rate.nextStartTime.Load()) <= rateMeasurementGranularity*2 for { - buffTail = atomic.LoadUint32(&tun.rings.Send.Ring.Tail) - if buffHead != buffTail { - break - } - if tun.close { + if tun.close.Load() { return 0, os.ErrClosed } - if !shouldSpin || uint64(nanotime()-start) >= spinloopDuration { - windows.WaitForSingleObject(tun.rings.Send.TailMoved, windows.INFINITE) - goto retry + packet, err := tun.session.ReceivePacket() + switch err { + case nil: + packetSize := len(packet) + copy(buff[offset:], packet) + tun.session.ReleaseReceivePacket(packet) + tun.rate.update(uint64(packetSize)) + return packetSize, nil + case windows.ERROR_NO_MORE_ITEMS: + if !shouldSpin || uint64(nanotime()-start) >= spinloopDuration { + windows.WaitForSingleObject(tun.readWait, windows.INFINITE) + goto retry + } + procyield(1) + continue + case windows.ERROR_HANDLE_EOF: + return 0, os.ErrClosed + case windows.ERROR_INVALID_DATA: + return 0, errors.New("Send ring corrupt") } - procyield(1) - } - if buffTail >= wintun.PacketCapacity { - return 0, os.ErrClosed - } - - buffContent := tun.rings.Send.Ring.Wrap(buffTail - buffHead) - if buffContent < uint32(unsafe.Sizeof(wintun.PacketHeader{})) { - return 0, errors.New("incomplete packet header in send ring") - } - - packet := (*wintun.Packet)(unsafe.Pointer(&tun.rings.Send.Ring.Data[buffHead])) - if packet.Size > wintun.PacketSizeMax { - return 0, errors.New("packet too big in send ring") - } - - alignedPacketSize := wintun.PacketAlign(uint32(unsafe.Sizeof(wintun.PacketHeader{})) + packet.Size) - if alignedPacketSize > buffContent { - return 0, errors.New("incomplete packet in send ring") + return 0, fmt.Errorf("Read failed: %w", err) } - - copy(buff[offset:], packet.Data[:packet.Size]) - buffHead = tun.rings.Send.Ring.Wrap(buffHead + alignedPacketSize) - atomic.StoreUint32(&tun.rings.Send.Ring.Head, buffHead) - tun.rate.update(uint64(packet.Size)) - return int(packet.Size), nil } func (tun *NativeTun) Flush() error { @@ -213,63 +178,56 @@ func (tun *NativeTun) Flush() error { } func (tun *NativeTun) Write(buff []byte, offset int) (int, error) { - if tun.close { + tun.running.Add(1) + defer tun.running.Done() + if tun.close.Load() { return 0, os.ErrClosed } - packetSize := uint32(len(buff) - offset) + packetSize := len(buff) - offset tun.rate.update(uint64(packetSize)) - alignedPacketSize := wintun.PacketAlign(uint32(unsafe.Sizeof(wintun.PacketHeader{})) + packetSize) - - tun.writeLock.Lock() - defer tun.writeLock.Unlock() - buffHead := atomic.LoadUint32(&tun.rings.Receive.Ring.Head) - if buffHead >= wintun.PacketCapacity { - return 0, os.ErrClosed + packet, err := tun.session.AllocateSendPacket(packetSize) + if err == nil { + copy(packet, buff[offset:]) + tun.session.SendPacket(packet) + return packetSize, nil } - - buffTail := atomic.LoadUint32(&tun.rings.Receive.Ring.Tail) - if buffTail >= wintun.PacketCapacity { + switch err { + case windows.ERROR_HANDLE_EOF: return 0, os.ErrClosed - } - - buffSpace := tun.rings.Receive.Ring.Wrap(buffHead - buffTail - wintun.PacketAlignment) - if alignedPacketSize > buffSpace { + case windows.ERROR_BUFFER_OVERFLOW: return 0, nil // Dropping when ring is full. } - - packet := (*wintun.Packet)(unsafe.Pointer(&tun.rings.Receive.Ring.Data[buffTail])) - packet.Size = packetSize - copy(packet.Data[:packetSize], buff[offset:]) - atomic.StoreUint32(&tun.rings.Receive.Ring.Tail, tun.rings.Receive.Ring.Wrap(buffTail+alignedPacketSize)) - if atomic.LoadInt32(&tun.rings.Receive.Ring.Alertable) != 0 { - windows.SetEvent(tun.rings.Receive.TailMoved) - } - return int(packetSize), nil + return 0, fmt.Errorf("Write failed: %w", err) } // LUID returns Windows interface instance ID. func (tun *NativeTun) LUID() uint64 { + tun.running.Add(1) + defer tun.running.Done() + if tun.close.Load() { + return 0 + } return tun.wt.LUID() } -// Version returns the version of the Wintun driver and NDIS system currently loaded. -func (tun *NativeTun) Version() (driverVersion string, ndisVersion string, err error) { - return tun.wt.Version() +// RunningVersion returns the running version of the Wintun driver. +func (tun *NativeTun) RunningVersion() (version uint32, err error) { + return wintun.RunningVersion() } func (rate *rateJuggler) update(packetLen uint64) { now := nanotime() - total := atomic.AddUint64(&rate.nextByteCount, packetLen) - period := uint64(now - atomic.LoadInt64(&rate.nextStartTime)) + total := rate.nextByteCount.Add(packetLen) + period := uint64(now - rate.nextStartTime.Load()) if period >= rateMeasurementGranularity { - if !atomic.CompareAndSwapInt32(&rate.changing, 0, 1) { + if !rate.changing.CompareAndSwap(false, true) { return } - atomic.StoreInt64(&rate.nextStartTime, now) - atomic.StoreUint64(&rate.current, total*uint64(time.Second/time.Nanosecond)/period) - atomic.StoreUint64(&rate.nextByteCount, 0) - atomic.StoreInt32(&rate.changing, 0) + rate.nextStartTime.Store(now) + rate.current.Store(total * uint64(time.Second/time.Nanosecond) / period) + rate.nextByteCount.Store(0) + rate.changing.Store(false) } } diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/iphlpapi/conversion_windows.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/iphlpapi/conversion_windows.go deleted file mode 100644 index a19e961eef..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/iphlpapi/conversion_windows.go +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package iphlpapi - -import "golang.org/x/sys/windows" - -//sys convertInterfaceLUIDToGUID(interfaceLUID *uint64, interfaceGUID *windows.GUID) (ret error) = iphlpapi.ConvertInterfaceLuidToGuid -//sys convertInterfaceAliasToLUID(interfaceAlias *uint16, interfaceLUID *uint64) (ret error) = iphlpapi.ConvertInterfaceAliasToLuid - -func InterfaceGUIDFromAlias(alias string) (*windows.GUID, error) { - var luid uint64 - var guid windows.GUID - err := convertInterfaceAliasToLUID(windows.StringToUTF16Ptr(alias), &luid) - if err != nil { - return nil, err - } - err = convertInterfaceLUIDToGUID(&luid, &guid) - if err != nil { - return nil, err - } - return &guid, nil -} diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/iphlpapi/mksyscall.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/iphlpapi/mksyscall.go deleted file mode 100644 index fc7dba41a6..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/iphlpapi/mksyscall.go +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package iphlpapi - -//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go conversion_windows.go diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/iphlpapi/zsyscall_windows.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/iphlpapi/zsyscall_windows.go deleted file mode 100644 index dc14294331..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/iphlpapi/zsyscall_windows.go +++ /dev/null @@ -1,60 +0,0 @@ -// Code generated by 'go generate'; DO NOT EDIT. - -package iphlpapi - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -var _ unsafe.Pointer - -// Do the interface allocations only once for common -// Errno values. -const ( - errnoERROR_IO_PENDING = 997 -) - -var ( - errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) -) - -// errnoErr returns common boxed Errno values, to prevent -// allocations at runtime. -func errnoErr(e syscall.Errno) error { - switch e { - case 0: - return nil - case errnoERROR_IO_PENDING: - return errERROR_IO_PENDING - } - // TODO: add more here, after collecting data on the common - // error values see on Windows. (perhaps when running - // all.bat?) - return e -} - -var ( - modiphlpapi = windows.NewLazySystemDLL("iphlpapi.dll") - - procConvertInterfaceLuidToGuid = modiphlpapi.NewProc("ConvertInterfaceLuidToGuid") - procConvertInterfaceAliasToLuid = modiphlpapi.NewProc("ConvertInterfaceAliasToLuid") -) - -func convertInterfaceLUIDToGUID(interfaceLUID *uint64, interfaceGUID *windows.GUID) (ret error) { - r0, _, _ := syscall.Syscall(procConvertInterfaceLuidToGuid.Addr(), 2, uintptr(unsafe.Pointer(interfaceLUID)), uintptr(unsafe.Pointer(interfaceGUID)), 0) - if r0 != 0 { - ret = syscall.Errno(r0) - } - return -} - -func convertInterfaceAliasToLUID(interfaceAlias *uint16, interfaceLUID *uint64) (ret error) { - r0, _, _ := syscall.Syscall(procConvertInterfaceAliasToLuid.Addr(), 2, uintptr(unsafe.Pointer(interfaceAlias)), uintptr(unsafe.Pointer(interfaceLUID)), 0) - if r0 != 0 { - ret = syscall.Errno(r0) - } - return -} diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/namespace_windows.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/namespace_windows.go deleted file mode 100644 index f4316fe84a..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/namespace_windows.go +++ /dev/null @@ -1,98 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package wintun - -import ( - "encoding/hex" - "errors" - "fmt" - "sync" - "unsafe" - - "golang.org/x/crypto/blake2s" - "golang.org/x/sys/windows" - "golang.org/x/text/unicode/norm" - - "golang.zx2c4.com/wireguard/tun/wintun/namespaceapi" -) - -var ( - wintunObjectSecurityAttributes *windows.SecurityAttributes - hasInitializedNamespace bool - initializingNamespace sync.Mutex -) - -func initializeNamespace() error { - initializingNamespace.Lock() - defer initializingNamespace.Unlock() - if hasInitializedNamespace { - return nil - } - sd, err := windows.SecurityDescriptorFromString("O:SYD:P(A;;GA;;;SY)") - if err != nil { - return fmt.Errorf("SddlToSecurityDescriptor failed: %v", err) - } - wintunObjectSecurityAttributes = &windows.SecurityAttributes{ - Length: uint32(unsafe.Sizeof(windows.SecurityAttributes{})), - SecurityDescriptor: sd, - } - sid, err := windows.CreateWellKnownSid(windows.WinLocalSystemSid) - if err != nil { - return fmt.Errorf("CreateWellKnownSid(LOCAL_SYSTEM) failed: %v", err) - } - - boundary, err := namespaceapi.CreateBoundaryDescriptor("Wintun") - if err != nil { - return fmt.Errorf("CreateBoundaryDescriptor failed: %v", err) - } - err = boundary.AddSid(sid) - if err != nil { - return fmt.Errorf("AddSIDToBoundaryDescriptor failed: %v", err) - } - for { - _, err = namespaceapi.CreatePrivateNamespace(wintunObjectSecurityAttributes, boundary, "Wintun") - if err == windows.ERROR_ALREADY_EXISTS { - _, err = namespaceapi.OpenPrivateNamespace(boundary, "Wintun") - if err == windows.ERROR_PATH_NOT_FOUND { - continue - } - } - if err != nil { - return fmt.Errorf("Create/OpenPrivateNamespace failed: %v", err) - } - break - } - hasInitializedNamespace = true - return nil -} - -func (pool Pool) takeNameMutex() (windows.Handle, error) { - err := initializeNamespace() - if err != nil { - return 0, err - } - - const mutexLabel = "WireGuard Adapter Name Mutex Stable Suffix v1 jason@zx2c4.com" - b2, _ := blake2s.New256(nil) - b2.Write([]byte(mutexLabel)) - b2.Write(norm.NFC.Bytes([]byte(string(pool)))) - mutexName := `Wintun\Wintun-Name-Mutex-` + hex.EncodeToString(b2.Sum(nil)) - mutex, err := windows.CreateMutex(wintunObjectSecurityAttributes, false, windows.StringToUTF16Ptr(mutexName)) - if err != nil { - err = fmt.Errorf("Error creating name mutex: %v", err) - return 0, err - } - event, err := windows.WaitForSingleObject(mutex, windows.INFINITE) - if err != nil { - windows.CloseHandle(mutex) - return 0, fmt.Errorf("Error waiting on name mutex: %v", err) - } - if event != windows.WAIT_OBJECT_0 && event != windows.WAIT_ABANDONED { - windows.CloseHandle(mutex) - return 0, errors.New("Error with event trigger of name mutex") - } - return mutex, nil -} diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/namespaceapi/mksyscall.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/namespaceapi/mksyscall.go deleted file mode 100644 index 93d43b0d2e..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/namespaceapi/mksyscall.go +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package namespaceapi - -//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go namespaceapi_windows.go diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/namespaceapi/namespaceapi_windows.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/namespaceapi/namespaceapi_windows.go deleted file mode 100644 index a3a62746e9..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/namespaceapi/namespaceapi_windows.go +++ /dev/null @@ -1,83 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package namespaceapi - -import "golang.org/x/sys/windows" - -//sys createBoundaryDescriptor(name *uint16, flags uint32) (handle windows.Handle, err error) = kernel32.CreateBoundaryDescriptorW -//sys deleteBoundaryDescriptor(boundaryDescriptor windows.Handle) = kernel32.DeleteBoundaryDescriptor -//sys addSIDToBoundaryDescriptor(boundaryDescriptor *windows.Handle, requiredSid *windows.SID) (err error) = kernel32.AddSIDToBoundaryDescriptor -//sys createPrivateNamespace(privateNamespaceAttributes *windows.SecurityAttributes, boundaryDescriptor windows.Handle, aliasPrefix *uint16) (handle windows.Handle, err error) = kernel32.CreatePrivateNamespaceW -//sys openPrivateNamespace(boundaryDescriptor windows.Handle, aliasPrefix *uint16) (handle windows.Handle, err error) = kernel32.OpenPrivateNamespaceW -//sys closePrivateNamespace(handle windows.Handle, flags uint32) (err error) = kernel32.ClosePrivateNamespace - -// BoundaryDescriptor represents a boundary that defines how the objects in the namespace are to be isolated. -type BoundaryDescriptor windows.Handle - -// CreateBoundaryDescriptor creates a boundary descriptor. -func CreateBoundaryDescriptor(name string) (BoundaryDescriptor, error) { - name16, err := windows.UTF16PtrFromString(name) - if err != nil { - return 0, err - } - handle, err := createBoundaryDescriptor(name16, 0) - if err != nil { - return 0, err - } - return BoundaryDescriptor(handle), nil -} - -// Delete deletes the specified boundary descriptor. -func (bd BoundaryDescriptor) Delete() { - deleteBoundaryDescriptor(windows.Handle(bd)) -} - -// AddSid adds a security identifier (SID) to the specified boundary descriptor. -func (bd *BoundaryDescriptor) AddSid(requiredSid *windows.SID) error { - return addSIDToBoundaryDescriptor((*windows.Handle)(bd), requiredSid) -} - -// PrivateNamespace represents a private namespace. -type PrivateNamespace windows.Handle - -// CreatePrivateNamespace creates a private namespace. -func CreatePrivateNamespace(privateNamespaceAttributes *windows.SecurityAttributes, boundaryDescriptor BoundaryDescriptor, aliasPrefix string) (PrivateNamespace, error) { - aliasPrefix16, err := windows.UTF16PtrFromString(aliasPrefix) - if err != nil { - return 0, err - } - handle, err := createPrivateNamespace(privateNamespaceAttributes, windows.Handle(boundaryDescriptor), aliasPrefix16) - if err != nil { - return 0, err - } - return PrivateNamespace(handle), nil -} - -// OpenPrivateNamespace opens a private namespace. -func OpenPrivateNamespace(boundaryDescriptor BoundaryDescriptor, aliasPrefix string) (PrivateNamespace, error) { - aliasPrefix16, err := windows.UTF16PtrFromString(aliasPrefix) - if err != nil { - return 0, err - } - handle, err := openPrivateNamespace(windows.Handle(boundaryDescriptor), aliasPrefix16) - if err != nil { - return 0, err - } - return PrivateNamespace(handle), nil -} - -// ClosePrivateNamespaceFlags describes flags that are used by PrivateNamespace's Close() method. -type ClosePrivateNamespaceFlags uint32 - -const ( - // PrivateNamespaceFlagDestroy makes the close to destroy the namespace. - PrivateNamespaceFlagDestroy = ClosePrivateNamespaceFlags(0x1) -) - -// Close closes an open namespace handle. -func (pns PrivateNamespace) Close(flags ClosePrivateNamespaceFlags) error { - return closePrivateNamespace(windows.Handle(pns), uint32(flags)) -} diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/namespaceapi/zsyscall_windows.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/namespaceapi/zsyscall_windows.go deleted file mode 100644 index 508c223bf6..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/namespaceapi/zsyscall_windows.go +++ /dev/null @@ -1,116 +0,0 @@ -// Code generated by 'go generate'; DO NOT EDIT. - -package namespaceapi - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -var _ unsafe.Pointer - -// Do the interface allocations only once for common -// Errno values. -const ( - errnoERROR_IO_PENDING = 997 -) - -var ( - errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) -) - -// errnoErr returns common boxed Errno values, to prevent -// allocations at runtime. -func errnoErr(e syscall.Errno) error { - switch e { - case 0: - return nil - case errnoERROR_IO_PENDING: - return errERROR_IO_PENDING - } - // TODO: add more here, after collecting data on the common - // error values see on Windows. (perhaps when running - // all.bat?) - return e -} - -var ( - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - - procCreateBoundaryDescriptorW = modkernel32.NewProc("CreateBoundaryDescriptorW") - procDeleteBoundaryDescriptor = modkernel32.NewProc("DeleteBoundaryDescriptor") - procAddSIDToBoundaryDescriptor = modkernel32.NewProc("AddSIDToBoundaryDescriptor") - procCreatePrivateNamespaceW = modkernel32.NewProc("CreatePrivateNamespaceW") - procOpenPrivateNamespaceW = modkernel32.NewProc("OpenPrivateNamespaceW") - procClosePrivateNamespace = modkernel32.NewProc("ClosePrivateNamespace") -) - -func createBoundaryDescriptor(name *uint16, flags uint32) (handle windows.Handle, err error) { - r0, _, e1 := syscall.Syscall(procCreateBoundaryDescriptorW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(flags), 0) - handle = windows.Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func deleteBoundaryDescriptor(boundaryDescriptor windows.Handle) { - syscall.Syscall(procDeleteBoundaryDescriptor.Addr(), 1, uintptr(boundaryDescriptor), 0, 0) - return -} - -func addSIDToBoundaryDescriptor(boundaryDescriptor *windows.Handle, requiredSid *windows.SID) (err error) { - r1, _, e1 := syscall.Syscall(procAddSIDToBoundaryDescriptor.Addr(), 2, uintptr(unsafe.Pointer(boundaryDescriptor)), uintptr(unsafe.Pointer(requiredSid)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func createPrivateNamespace(privateNamespaceAttributes *windows.SecurityAttributes, boundaryDescriptor windows.Handle, aliasPrefix *uint16) (handle windows.Handle, err error) { - r0, _, e1 := syscall.Syscall(procCreatePrivateNamespaceW.Addr(), 3, uintptr(unsafe.Pointer(privateNamespaceAttributes)), uintptr(boundaryDescriptor), uintptr(unsafe.Pointer(aliasPrefix))) - handle = windows.Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func openPrivateNamespace(boundaryDescriptor windows.Handle, aliasPrefix *uint16) (handle windows.Handle, err error) { - r0, _, e1 := syscall.Syscall(procOpenPrivateNamespaceW.Addr(), 2, uintptr(boundaryDescriptor), uintptr(unsafe.Pointer(aliasPrefix)), 0) - handle = windows.Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func closePrivateNamespace(handle windows.Handle, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procClosePrivateNamespace.Addr(), 2, uintptr(handle), uintptr(flags), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/nci/mksyscall.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/nci/mksyscall.go deleted file mode 100644 index 019da93b02..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/nci/mksyscall.go +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package nci - -//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go nci_windows.go diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/nci/nci_windows.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/nci/nci_windows.go deleted file mode 100644 index 9dc669938c..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/nci/nci_windows.go +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package nci - -import "golang.org/x/sys/windows" - -//sys nciSetConnectionName(guid *windows.GUID, newName *uint16) (ret error) = nci.NciSetConnectionName -//sys nciGetConnectionName(guid *windows.GUID, destName *uint16, inDestNameBytes uint32, outDestNameBytes *uint32) (ret error) = nci.NciGetConnectionName - -func SetConnectionName(guid *windows.GUID, newName string) error { - newName16, err := windows.UTF16PtrFromString(newName) - if err != nil { - return err - } - return nciSetConnectionName(guid, newName16) -} - -func ConnectionName(guid *windows.GUID) (string, error) { - var name [0x400]uint16 - err := nciGetConnectionName(guid, &name[0], uint32(len(name)*2), nil) - if err != nil { - return "", err - } - return windows.UTF16ToString(name[:]), nil -} diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/nci/zsyscall_windows.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/nci/zsyscall_windows.go deleted file mode 100644 index 2a7b79ec9a..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/nci/zsyscall_windows.go +++ /dev/null @@ -1,60 +0,0 @@ -// Code generated by 'go generate'; DO NOT EDIT. - -package nci - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -var _ unsafe.Pointer - -// Do the interface allocations only once for common -// Errno values. -const ( - errnoERROR_IO_PENDING = 997 -) - -var ( - errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) -) - -// errnoErr returns common boxed Errno values, to prevent -// allocations at runtime. -func errnoErr(e syscall.Errno) error { - switch e { - case 0: - return nil - case errnoERROR_IO_PENDING: - return errERROR_IO_PENDING - } - // TODO: add more here, after collecting data on the common - // error values see on Windows. (perhaps when running - // all.bat?) - return e -} - -var ( - modnci = windows.NewLazySystemDLL("nci.dll") - - procNciSetConnectionName = modnci.NewProc("NciSetConnectionName") - procNciGetConnectionName = modnci.NewProc("NciGetConnectionName") -) - -func nciSetConnectionName(guid *windows.GUID, newName *uint16) (ret error) { - r0, _, _ := syscall.Syscall(procNciSetConnectionName.Addr(), 2, uintptr(unsafe.Pointer(guid)), uintptr(unsafe.Pointer(newName)), 0) - if r0 != 0 { - ret = syscall.Errno(r0) - } - return -} - -func nciGetConnectionName(guid *windows.GUID, destName *uint16, inDestNameBytes uint32, outDestNameBytes *uint32) (ret error) { - r0, _, _ := syscall.Syscall6(procNciGetConnectionName.Addr(), 4, uintptr(unsafe.Pointer(guid)), uintptr(unsafe.Pointer(destName)), uintptr(inDestNameBytes), uintptr(unsafe.Pointer(outDestNameBytes)), 0, 0) - if r0 != 0 { - ret = syscall.Errno(r0) - } - return -} diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/registry/mksyscall.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/registry/mksyscall.go deleted file mode 100644 index 6ad82d2209..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/registry/mksyscall.go +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package registry - -//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zregistry_windows.go registry_windows.go diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/registry/registry_windows.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/registry/registry_windows.go deleted file mode 100644 index 12a0336203..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/registry/registry_windows.go +++ /dev/null @@ -1,272 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package registry - -import ( - "errors" - "fmt" - "runtime" - "strings" - "time" - "unsafe" - - "golang.org/x/sys/windows" - "golang.org/x/sys/windows/registry" -) - -const ( - // REG_NOTIFY_CHANGE_NAME notifies the caller if a subkey is added or deleted. - REG_NOTIFY_CHANGE_NAME uint32 = 0x00000001 - - // REG_NOTIFY_CHANGE_ATTRIBUTES notifies the caller of changes to the attributes of the key, such as the security descriptor information. - REG_NOTIFY_CHANGE_ATTRIBUTES uint32 = 0x00000002 - - // REG_NOTIFY_CHANGE_LAST_SET notifies the caller of changes to a value of the key. This can include adding or deleting a value, or changing an existing value. - REG_NOTIFY_CHANGE_LAST_SET uint32 = 0x00000004 - - // REG_NOTIFY_CHANGE_SECURITY notifies the caller of changes to the security descriptor of the key. - REG_NOTIFY_CHANGE_SECURITY uint32 = 0x00000008 - - // REG_NOTIFY_THREAD_AGNOSTIC indicates that the lifetime of the registration must not be tied to the lifetime of the thread issuing the RegNotifyChangeKeyValue call. Note: This flag value is only supported in Windows 8 and later. - REG_NOTIFY_THREAD_AGNOSTIC uint32 = 0x10000000 -) - -//sys regNotifyChangeKeyValue(key windows.Handle, watchSubtree bool, notifyFilter uint32, event windows.Handle, asynchronous bool) (regerrno error) = advapi32.RegNotifyChangeKeyValue - -func OpenKeyWait(k registry.Key, path string, access uint32, timeout time.Duration) (registry.Key, error) { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - deadline := time.Now().Add(timeout) - pathSpl := strings.Split(path, "\\") - for i := 0; ; i++ { - keyName := pathSpl[i] - isLast := i+1 == len(pathSpl) - - event, err := windows.CreateEvent(nil, 0, 0, nil) - if err != nil { - return 0, fmt.Errorf("Error creating event: %v", err) - } - defer windows.CloseHandle(event) - - var key registry.Key - for { - err = regNotifyChangeKeyValue(windows.Handle(k), false, REG_NOTIFY_CHANGE_NAME, windows.Handle(event), true) - if err != nil { - return 0, fmt.Errorf("Setting up change notification on registry key failed: %v", err) - } - - var accessFlags uint32 - if isLast { - accessFlags = access - } else { - accessFlags = registry.NOTIFY - } - key, err = registry.OpenKey(k, keyName, accessFlags) - if err == windows.ERROR_FILE_NOT_FOUND || err == windows.ERROR_PATH_NOT_FOUND { - timeout := time.Until(deadline) / time.Millisecond - if timeout < 0 { - timeout = 0 - } - s, err := windows.WaitForSingleObject(event, uint32(timeout)) - if err != nil { - return 0, fmt.Errorf("Unable to wait on registry key: %v", err) - } - if s == uint32(windows.WAIT_TIMEOUT) { // windows.WAIT_TIMEOUT status const is misclassified as error in golang.org/x/sys/windows - return 0, errors.New("Timeout waiting for registry key") - } - } else if err != nil { - return 0, fmt.Errorf("Error opening registry key %v: %v", path, err) - } else { - if isLast { - return key, nil - } - defer key.Close() - break - } - } - - k = key - } -} - -func WaitForKey(k registry.Key, path string, timeout time.Duration) error { - key, err := OpenKeyWait(k, path, registry.NOTIFY, timeout) - if err != nil { - return err - } - key.Close() - return nil -} - -// -// getValue is more or less the same as windows/registry's getValue. -// -func getValue(k registry.Key, name string, buf []byte) (value []byte, valueType uint32, err error) { - var name16 *uint16 - name16, err = windows.UTF16PtrFromString(name) - if err != nil { - return - } - n := uint32(len(buf)) - for { - err = windows.RegQueryValueEx(windows.Handle(k), name16, nil, &valueType, (*byte)(unsafe.Pointer(&buf[0])), &n) - if err == nil { - value = buf[:n] - return - } - if err != windows.ERROR_MORE_DATA { - return - } - if n <= uint32(len(buf)) { - return - } - buf = make([]byte, n) - } -} - -// -// getValueRetry function reads any value from registry. It waits for -// the registry value to become available or returns error on timeout. -// -// Key must be opened with at least QUERY_VALUE|NOTIFY access. -// -func getValueRetry(key registry.Key, name string, buf []byte, timeout time.Duration) ([]byte, uint32, error) { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - event, err := windows.CreateEvent(nil, 0, 0, nil) - if err != nil { - return nil, 0, fmt.Errorf("Error creating event: %v", err) - } - defer windows.CloseHandle(event) - - deadline := time.Now().Add(timeout) - for { - err := regNotifyChangeKeyValue(windows.Handle(key), false, REG_NOTIFY_CHANGE_LAST_SET, windows.Handle(event), true) - if err != nil { - return nil, 0, fmt.Errorf("Setting up change notification on registry value failed: %v", err) - } - - buf, valueType, err := getValue(key, name, buf) - if err == windows.ERROR_FILE_NOT_FOUND || err == windows.ERROR_PATH_NOT_FOUND { - timeout := time.Until(deadline) / time.Millisecond - if timeout < 0 { - timeout = 0 - } - s, err := windows.WaitForSingleObject(event, uint32(timeout)) - if err != nil { - return nil, 0, fmt.Errorf("Unable to wait on registry value: %v", err) - } - if s == uint32(windows.WAIT_TIMEOUT) { // windows.WAIT_TIMEOUT status const is misclassified as error in golang.org/x/sys/windows - return nil, 0, errors.New("Timeout waiting for registry value") - } - } else if err != nil { - return nil, 0, fmt.Errorf("Error reading registry value %v: %v", name, err) - } else { - return buf, valueType, nil - } - } -} - -func toString(buf []byte, valueType uint32, err error) (string, error) { - if err != nil { - return "", err - } - - var value string - switch valueType { - case registry.SZ, registry.EXPAND_SZ, registry.MULTI_SZ: - if len(buf) == 0 { - return "", nil - } - value = windows.UTF16ToString((*[(1 << 30) - 1]uint16)(unsafe.Pointer(&buf[0]))[:len(buf)/2]) - - default: - return "", registry.ErrUnexpectedType - } - - if valueType != registry.EXPAND_SZ { - // Value does not require expansion. - return value, nil - } - - valueExp, err := registry.ExpandString(value) - if err != nil { - // Expanding failed: return original sting value. - return value, nil - } - - // Return expanded value. - return valueExp, nil -} - -func toInteger(buf []byte, valueType uint32, err error) (uint64, error) { - if err != nil { - return 0, err - } - - switch valueType { - case registry.DWORD: - if len(buf) != 4 { - return 0, errors.New("DWORD value is not 4 bytes long") - } - var val uint32 - copy((*[4]byte)(unsafe.Pointer(&val))[:], buf) - return uint64(val), nil - - case registry.QWORD: - if len(buf) != 8 { - return 0, errors.New("QWORD value is not 8 bytes long") - } - var val uint64 - copy((*[8]byte)(unsafe.Pointer(&val))[:], buf) - return val, nil - - default: - return 0, registry.ErrUnexpectedType - } -} - -// -// GetStringValueWait function reads a string value from registry. It waits -// for the registry value to become available or returns error on timeout. -// -// Key must be opened with at least QUERY_VALUE|NOTIFY access. -// -// If the value type is REG_EXPAND_SZ the environment variables are expanded. -// Should expanding fail, original string value and nil error are returned. -// -// If the value type is REG_MULTI_SZ only the first string is returned. -// -func GetStringValueWait(key registry.Key, name string, timeout time.Duration) (string, error) { - return toString(getValueRetry(key, name, make([]byte, 256), timeout)) -} - -// -// GetStringValue function reads a string value from registry. -// -// Key must be opened with at least QUERY_VALUE access. -// -// If the value type is REG_EXPAND_SZ the environment variables are expanded. -// Should expanding fail, original string value and nil error are returned. -// -// If the value type is REG_MULTI_SZ only the first string is returned. -// -func GetStringValue(key registry.Key, name string) (string, error) { - return toString(getValue(key, name, make([]byte, 256))) -} - -// -// GetIntegerValueWait function reads a DWORD32 or QWORD value from registry. -// It waits for the registry value to become available or returns error on -// timeout. -// -// Key must be opened with at least QUERY_VALUE|NOTIFY access. -// -func GetIntegerValueWait(key registry.Key, name string, timeout time.Duration) (uint64, error) { - return toInteger(getValueRetry(key, name, make([]byte, 8), timeout)) -} diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/registry/zregistry_windows.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/registry/zregistry_windows.go deleted file mode 100644 index f7ac33be95..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/registry/zregistry_windows.go +++ /dev/null @@ -1,63 +0,0 @@ -// Code generated by 'go generate'; DO NOT EDIT. - -package registry - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -var _ unsafe.Pointer - -// Do the interface allocations only once for common -// Errno values. -const ( - errnoERROR_IO_PENDING = 997 -) - -var ( - errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) -) - -// errnoErr returns common boxed Errno values, to prevent -// allocations at runtime. -func errnoErr(e syscall.Errno) error { - switch e { - case 0: - return nil - case errnoERROR_IO_PENDING: - return errERROR_IO_PENDING - } - // TODO: add more here, after collecting data on the common - // error values see on Windows. (perhaps when running - // all.bat?) - return e -} - -var ( - modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") - - procRegNotifyChangeKeyValue = modadvapi32.NewProc("RegNotifyChangeKeyValue") -) - -func regNotifyChangeKeyValue(key windows.Handle, watchSubtree bool, notifyFilter uint32, event windows.Handle, asynchronous bool) (regerrno error) { - var _p0 uint32 - if watchSubtree { - _p0 = 1 - } else { - _p0 = 0 - } - var _p1 uint32 - if asynchronous { - _p1 = 1 - } else { - _p1 = 0 - } - r0, _, _ := syscall.Syscall6(procRegNotifyChangeKeyValue.Addr(), 5, uintptr(key), uintptr(_p0), uintptr(notifyFilter), uintptr(event), uintptr(_p1), 0) - if r0 != 0 { - regerrno = syscall.Errno(r0) - } - return -} diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/ring_windows.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/ring_windows.go deleted file mode 100644 index 8e6b37584d..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/ring_windows.go +++ /dev/null @@ -1,117 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package wintun - -import ( - "runtime" - "unsafe" - - "golang.org/x/sys/windows" -) - -const ( - PacketAlignment = 4 // Number of bytes packets are aligned to in rings - PacketSizeMax = 0xffff // Maximum packet size - PacketCapacity = 0x800000 // Ring capacity, 8MiB - PacketTrailingSize = uint32(unsafe.Sizeof(PacketHeader{})) + ((PacketSizeMax + (PacketAlignment - 1)) &^ (PacketAlignment - 1)) - PacketAlignment - ioctlRegisterRings = (51820 << 16) | (0x970 << 2) | 0 /*METHOD_BUFFERED*/ | (0x3 /*FILE_READ_DATA | FILE_WRITE_DATA*/ << 14) -) - -type PacketHeader struct { - Size uint32 -} - -type Packet struct { - PacketHeader - Data [PacketSizeMax]byte -} - -type Ring struct { - Head uint32 - Tail uint32 - Alertable int32 - Data [PacketCapacity + PacketTrailingSize]byte -} - -type RingDescriptor struct { - Send, Receive struct { - Size uint32 - Ring *Ring - TailMoved windows.Handle - } -} - -// Wrap returns value modulo ring capacity -func (rb *Ring) Wrap(value uint32) uint32 { - return value & (PacketCapacity - 1) -} - -// Aligns a packet size to PacketAlignment -func PacketAlign(size uint32) uint32 { - return (size + (PacketAlignment - 1)) &^ (PacketAlignment - 1) -} - -func NewRingDescriptor() (descriptor *RingDescriptor, err error) { - descriptor = new(RingDescriptor) - allocatedRegion, err := windows.VirtualAlloc(0, unsafe.Sizeof(Ring{})*2, windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_READWRITE) - if err != nil { - return - } - defer func() { - if err != nil { - descriptor.free() - descriptor = nil - } - }() - descriptor.Send.Size = uint32(unsafe.Sizeof(Ring{})) - descriptor.Send.Ring = (*Ring)(unsafe.Pointer(allocatedRegion)) - descriptor.Send.TailMoved, err = windows.CreateEvent(nil, 0, 0, nil) - if err != nil { - return - } - - descriptor.Receive.Size = uint32(unsafe.Sizeof(Ring{})) - descriptor.Receive.Ring = (*Ring)(unsafe.Pointer(allocatedRegion + unsafe.Sizeof(Ring{}))) - descriptor.Receive.TailMoved, err = windows.CreateEvent(nil, 0, 0, nil) - if err != nil { - windows.CloseHandle(descriptor.Send.TailMoved) - return - } - runtime.SetFinalizer(descriptor, func(d *RingDescriptor) { d.free() }) - return -} - -func (descriptor *RingDescriptor) free() { - if descriptor.Send.Ring != nil { - windows.VirtualFree(uintptr(unsafe.Pointer(descriptor.Send.Ring)), 0, windows.MEM_RELEASE) - descriptor.Send.Ring = nil - descriptor.Receive.Ring = nil - } -} - -func (descriptor *RingDescriptor) Close() { - if descriptor.Send.TailMoved != 0 { - windows.CloseHandle(descriptor.Send.TailMoved) - descriptor.Send.TailMoved = 0 - } - if descriptor.Send.TailMoved != 0 { - windows.CloseHandle(descriptor.Receive.TailMoved) - descriptor.Receive.TailMoved = 0 - } -} - -func (wintun *Interface) Register(descriptor *RingDescriptor) (windows.Handle, error) { - handle, err := wintun.handle() - if err != nil { - return 0, err - } - var bytesReturned uint32 - err = windows.DeviceIoControl(handle, ioctlRegisterRings, (*byte)(unsafe.Pointer(descriptor)), uint32(unsafe.Sizeof(*descriptor)), nil, 0, &bytesReturned, nil) - if err != nil { - return 0, err - } - return handle, nil -} diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/mksyscall.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/mksyscall.go deleted file mode 100644 index ac103a1d3b..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/mksyscall.go +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package setupapi - -//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsetupapi_windows.go setupapi_windows.go diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/setupapi_windows.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/setupapi_windows.go deleted file mode 100644 index 60a8eb7342..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/setupapi_windows.go +++ /dev/null @@ -1,506 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package setupapi - -import ( - "encoding/binary" - "fmt" - "runtime" - "unsafe" - - "golang.org/x/sys/windows" - "golang.org/x/sys/windows/registry" -) - -//sys setupDiCreateDeviceInfoListEx(classGUID *windows.GUID, hwndParent uintptr, machineName *uint16, reserved uintptr) (handle DevInfo, err error) [failretval==DevInfo(windows.InvalidHandle)] = setupapi.SetupDiCreateDeviceInfoListExW - -// SetupDiCreateDeviceInfoListEx function creates an empty device information set on a remote or a local computer and optionally associates the set with a device setup class. -func SetupDiCreateDeviceInfoListEx(classGUID *windows.GUID, hwndParent uintptr, machineName string) (deviceInfoSet DevInfo, err error) { - var machineNameUTF16 *uint16 - if machineName != "" { - machineNameUTF16, err = windows.UTF16PtrFromString(machineName) - if err != nil { - return - } - } - return setupDiCreateDeviceInfoListEx(classGUID, hwndParent, machineNameUTF16, 0) -} - -//sys setupDiGetDeviceInfoListDetail(deviceInfoSet DevInfo, deviceInfoSetDetailData *DevInfoListDetailData) (err error) = setupapi.SetupDiGetDeviceInfoListDetailW - -// SetupDiGetDeviceInfoListDetail function retrieves information associated with a device information set including the class GUID, remote computer handle, and remote computer name. -func SetupDiGetDeviceInfoListDetail(deviceInfoSet DevInfo) (deviceInfoSetDetailData *DevInfoListDetailData, err error) { - data := &DevInfoListDetailData{} - data.size = sizeofDevInfoListDetailData - - return data, setupDiGetDeviceInfoListDetail(deviceInfoSet, data) -} - -// DeviceInfoListDetail method retrieves information associated with a device information set including the class GUID, remote computer handle, and remote computer name. -func (deviceInfoSet DevInfo) DeviceInfoListDetail() (*DevInfoListDetailData, error) { - return SetupDiGetDeviceInfoListDetail(deviceInfoSet) -} - -//sys setupDiCreateDeviceInfo(deviceInfoSet DevInfo, DeviceName *uint16, classGUID *windows.GUID, DeviceDescription *uint16, hwndParent uintptr, CreationFlags DICD, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiCreateDeviceInfoW - -// SetupDiCreateDeviceInfo function creates a new device information element and adds it as a new member to the specified device information set. -func SetupDiCreateDeviceInfo(deviceInfoSet DevInfo, deviceName string, classGUID *windows.GUID, deviceDescription string, hwndParent uintptr, creationFlags DICD) (deviceInfoData *DevInfoData, err error) { - deviceNameUTF16, err := windows.UTF16PtrFromString(deviceName) - if err != nil { - return - } - - var deviceDescriptionUTF16 *uint16 - if deviceDescription != "" { - deviceDescriptionUTF16, err = windows.UTF16PtrFromString(deviceDescription) - if err != nil { - return - } - } - - data := &DevInfoData{} - data.size = uint32(unsafe.Sizeof(*data)) - - return data, setupDiCreateDeviceInfo(deviceInfoSet, deviceNameUTF16, classGUID, deviceDescriptionUTF16, hwndParent, creationFlags, data) -} - -// CreateDeviceInfo method creates a new device information element and adds it as a new member to the specified device information set. -func (deviceInfoSet DevInfo) CreateDeviceInfo(deviceName string, classGUID *windows.GUID, deviceDescription string, hwndParent uintptr, creationFlags DICD) (*DevInfoData, error) { - return SetupDiCreateDeviceInfo(deviceInfoSet, deviceName, classGUID, deviceDescription, hwndParent, creationFlags) -} - -//sys setupDiEnumDeviceInfo(deviceInfoSet DevInfo, memberIndex uint32, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiEnumDeviceInfo - -// SetupDiEnumDeviceInfo function returns a DevInfoData structure that specifies a device information element in a device information set. -func SetupDiEnumDeviceInfo(deviceInfoSet DevInfo, memberIndex int) (*DevInfoData, error) { - data := &DevInfoData{} - data.size = uint32(unsafe.Sizeof(*data)) - - return data, setupDiEnumDeviceInfo(deviceInfoSet, uint32(memberIndex), data) -} - -// EnumDeviceInfo method returns a DevInfoData structure that specifies a device information element in a device information set. -func (deviceInfoSet DevInfo) EnumDeviceInfo(memberIndex int) (*DevInfoData, error) { - return SetupDiEnumDeviceInfo(deviceInfoSet, memberIndex) -} - -// SetupDiDestroyDeviceInfoList function deletes a device information set and frees all associated memory. -//sys SetupDiDestroyDeviceInfoList(deviceInfoSet DevInfo) (err error) = setupapi.SetupDiDestroyDeviceInfoList - -// Close method deletes a device information set and frees all associated memory. -func (deviceInfoSet DevInfo) Close() error { - return SetupDiDestroyDeviceInfoList(deviceInfoSet) -} - -//sys SetupDiBuildDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT) (err error) = setupapi.SetupDiBuildDriverInfoList - -// BuildDriverInfoList method builds a list of drivers that is associated with a specific device or with the global class driver list for a device information set. -func (deviceInfoSet DevInfo) BuildDriverInfoList(deviceInfoData *DevInfoData, driverType SPDIT) error { - return SetupDiBuildDriverInfoList(deviceInfoSet, deviceInfoData, driverType) -} - -//sys SetupDiCancelDriverInfoSearch(deviceInfoSet DevInfo) (err error) = setupapi.SetupDiCancelDriverInfoSearch - -// CancelDriverInfoSearch method cancels a driver list search that is currently in progress in a different thread. -func (deviceInfoSet DevInfo) CancelDriverInfoSearch() error { - return SetupDiCancelDriverInfoSearch(deviceInfoSet) -} - -//sys setupDiEnumDriverInfo(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT, memberIndex uint32, driverInfoData *DrvInfoData) (err error) = setupapi.SetupDiEnumDriverInfoW - -// SetupDiEnumDriverInfo function enumerates the members of a driver list. -func SetupDiEnumDriverInfo(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT, memberIndex int) (*DrvInfoData, error) { - data := &DrvInfoData{} - data.size = uint32(unsafe.Sizeof(*data)) - - return data, setupDiEnumDriverInfo(deviceInfoSet, deviceInfoData, driverType, uint32(memberIndex), data) -} - -// EnumDriverInfo method enumerates the members of a driver list. -func (deviceInfoSet DevInfo) EnumDriverInfo(deviceInfoData *DevInfoData, driverType SPDIT, memberIndex int) (*DrvInfoData, error) { - return SetupDiEnumDriverInfo(deviceInfoSet, deviceInfoData, driverType, memberIndex) -} - -//sys setupDiGetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (err error) = setupapi.SetupDiGetSelectedDriverW - -// SetupDiGetSelectedDriver function retrieves the selected driver for a device information set or a particular device information element. -func SetupDiGetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (*DrvInfoData, error) { - data := &DrvInfoData{} - data.size = uint32(unsafe.Sizeof(*data)) - - return data, setupDiGetSelectedDriver(deviceInfoSet, deviceInfoData, data) -} - -// SelectedDriver method retrieves the selected driver for a device information set or a particular device information element. -func (deviceInfoSet DevInfo) SelectedDriver(deviceInfoData *DevInfoData) (*DrvInfoData, error) { - return SetupDiGetSelectedDriver(deviceInfoSet, deviceInfoData) -} - -//sys SetupDiSetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (err error) = setupapi.SetupDiSetSelectedDriverW - -// SetSelectedDriver method sets, or resets, the selected driver for a device information element or the selected class driver for a device information set. -func (deviceInfoSet DevInfo) SetSelectedDriver(deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) error { - return SetupDiSetSelectedDriver(deviceInfoSet, deviceInfoData, driverInfoData) -} - -//sys setupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData, driverInfoDetailData *DrvInfoDetailData, driverInfoDetailDataSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiGetDriverInfoDetailW - -// SetupDiGetDriverInfoDetail function retrieves driver information detail for a device information set or a particular device information element in the device information set. -func SetupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (*DrvInfoDetailData, error) { - reqSize := uint32(2048) - for { - buf := make([]byte, reqSize) - data := (*DrvInfoDetailData)(unsafe.Pointer(&buf[0])) - data.size = sizeofDrvInfoDetailData - err := setupDiGetDriverInfoDetail(deviceInfoSet, deviceInfoData, driverInfoData, data, uint32(len(buf)), &reqSize) - if err == windows.ERROR_INSUFFICIENT_BUFFER { - continue - } - if err != nil { - return nil, err - } - data.size = reqSize - return data, nil - } -} - -// DriverInfoDetail method retrieves driver information detail for a device information set or a particular device information element in the device information set. -func (deviceInfoSet DevInfo) DriverInfoDetail(deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (*DrvInfoDetailData, error) { - return SetupDiGetDriverInfoDetail(deviceInfoSet, deviceInfoData, driverInfoData) -} - -//sys SetupDiDestroyDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT) (err error) = setupapi.SetupDiDestroyDriverInfoList - -// DestroyDriverInfoList method deletes a driver list. -func (deviceInfoSet DevInfo) DestroyDriverInfoList(deviceInfoData *DevInfoData, driverType SPDIT) error { - return SetupDiDestroyDriverInfoList(deviceInfoSet, deviceInfoData, driverType) -} - -//sys setupDiGetClassDevsEx(classGUID *windows.GUID, Enumerator *uint16, hwndParent uintptr, Flags DIGCF, deviceInfoSet DevInfo, machineName *uint16, reserved uintptr) (handle DevInfo, err error) [failretval==DevInfo(windows.InvalidHandle)] = setupapi.SetupDiGetClassDevsExW - -// SetupDiGetClassDevsEx function returns a handle to a device information set that contains requested device information elements for a local or a remote computer. -func SetupDiGetClassDevsEx(classGUID *windows.GUID, enumerator string, hwndParent uintptr, flags DIGCF, deviceInfoSet DevInfo, machineName string) (handle DevInfo, err error) { - var enumeratorUTF16 *uint16 - if enumerator != "" { - enumeratorUTF16, err = windows.UTF16PtrFromString(enumerator) - if err != nil { - return - } - } - var machineNameUTF16 *uint16 - if machineName != "" { - machineNameUTF16, err = windows.UTF16PtrFromString(machineName) - if err != nil { - return - } - } - return setupDiGetClassDevsEx(classGUID, enumeratorUTF16, hwndParent, flags, deviceInfoSet, machineNameUTF16, 0) -} - -// SetupDiCallClassInstaller function calls the appropriate class installer, and any registered co-installers, with the specified installation request (DIF code). -//sys SetupDiCallClassInstaller(installFunction DI_FUNCTION, deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiCallClassInstaller - -// CallClassInstaller member calls the appropriate class installer, and any registered co-installers, with the specified installation request (DIF code). -func (deviceInfoSet DevInfo) CallClassInstaller(installFunction DI_FUNCTION, deviceInfoData *DevInfoData) error { - return SetupDiCallClassInstaller(installFunction, deviceInfoSet, deviceInfoData) -} - -//sys setupDiOpenDevRegKey(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, Scope DICS_FLAG, HwProfile uint32, KeyType DIREG, samDesired uint32) (key windows.Handle, err error) [failretval==windows.InvalidHandle] = setupapi.SetupDiOpenDevRegKey - -// SetupDiOpenDevRegKey function opens a registry key for device-specific configuration information. -func SetupDiOpenDevRegKey(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, scope DICS_FLAG, hwProfile uint32, keyType DIREG, samDesired uint32) (registry.Key, error) { - handle, err := setupDiOpenDevRegKey(deviceInfoSet, deviceInfoData, scope, hwProfile, keyType, samDesired) - return registry.Key(handle), err -} - -// OpenDevRegKey method opens a registry key for device-specific configuration information. -func (deviceInfoSet DevInfo) OpenDevRegKey(DeviceInfoData *DevInfoData, Scope DICS_FLAG, HwProfile uint32, KeyType DIREG, samDesired uint32) (registry.Key, error) { - return SetupDiOpenDevRegKey(deviceInfoSet, DeviceInfoData, Scope, HwProfile, KeyType, samDesired) -} - -//sys setupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyRegDataType *uint32, propertyBuffer *byte, propertyBufferSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiGetDeviceRegistryPropertyW - -// SetupDiGetDeviceRegistryProperty function retrieves a specified Plug and Play device property. -func SetupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP) (value interface{}, err error) { - reqSize := uint32(256) - for { - var dataType uint32 - buf := make([]byte, reqSize) - err = setupDiGetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, &dataType, &buf[0], uint32(len(buf)), &reqSize) - if err == windows.ERROR_INSUFFICIENT_BUFFER { - continue - } - if err != nil { - return - } - return getRegistryValue(buf[:reqSize], dataType) - } -} - -func getRegistryValue(buf []byte, dataType uint32) (interface{}, error) { - switch dataType { - case windows.REG_SZ: - ret := windows.UTF16ToString(bufToUTF16(buf)) - runtime.KeepAlive(buf) - return ret, nil - case windows.REG_EXPAND_SZ: - ret, err := registry.ExpandString(windows.UTF16ToString(bufToUTF16(buf))) - runtime.KeepAlive(buf) - return ret, err - case windows.REG_BINARY: - return buf, nil - case windows.REG_DWORD_LITTLE_ENDIAN: - return binary.LittleEndian.Uint32(buf), nil - case windows.REG_DWORD_BIG_ENDIAN: - return binary.BigEndian.Uint32(buf), nil - case windows.REG_MULTI_SZ: - bufW := bufToUTF16(buf) - a := []string{} - for i := 0; i < len(bufW); { - j := i + wcslen(bufW[i:]) - if i < j { - a = append(a, windows.UTF16ToString(bufW[i:j])) - } - i = j + 1 - } - runtime.KeepAlive(buf) - return a, nil - case windows.REG_QWORD_LITTLE_ENDIAN: - return binary.LittleEndian.Uint64(buf), nil - default: - return nil, fmt.Errorf("Unsupported registry value type: %v", dataType) - } -} - -// bufToUTF16 function reinterprets []byte buffer as []uint16 -func bufToUTF16(buf []byte) []uint16 { - sl := struct { - addr *uint16 - len int - cap int - }{(*uint16)(unsafe.Pointer(&buf[0])), len(buf) / 2, cap(buf) / 2} - return *(*[]uint16)(unsafe.Pointer(&sl)) -} - -// utf16ToBuf function reinterprets []uint16 as []byte -func utf16ToBuf(buf []uint16) []byte { - sl := struct { - addr *byte - len int - cap int - }{(*byte)(unsafe.Pointer(&buf[0])), len(buf) * 2, cap(buf) * 2} - return *(*[]byte)(unsafe.Pointer(&sl)) -} - -func wcslen(str []uint16) int { - for i := 0; i < len(str); i++ { - if str[i] == 0 { - return i - } - } - return len(str) -} - -// DeviceRegistryProperty method retrieves a specified Plug and Play device property. -func (deviceInfoSet DevInfo) DeviceRegistryProperty(deviceInfoData *DevInfoData, property SPDRP) (interface{}, error) { - return SetupDiGetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property) -} - -//sys setupDiSetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyBuffer *byte, propertyBufferSize uint32) (err error) = setupapi.SetupDiSetDeviceRegistryPropertyW - -// SetupDiSetDeviceRegistryProperty function sets a Plug and Play device property for a device. -func SetupDiSetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyBuffers []byte) error { - return setupDiSetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, &propertyBuffers[0], uint32(len(propertyBuffers))) -} - -// SetDeviceRegistryProperty function sets a Plug and Play device property for a device. -func (deviceInfoSet DevInfo) SetDeviceRegistryProperty(deviceInfoData *DevInfoData, property SPDRP, propertyBuffers []byte) error { - return SetupDiSetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, propertyBuffers) -} - -// SetDeviceRegistryPropertyString method sets a Plug and Play device property string for a device. -func (deviceInfoSet DevInfo) SetDeviceRegistryPropertyString(deviceInfoData *DevInfoData, property SPDRP, str string) error { - str16, err := windows.UTF16FromString(str) - if err != nil { - return err - } - err = SetupDiSetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, utf16ToBuf(append(str16, 0))) - runtime.KeepAlive(str16) - return err -} - -//sys setupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) = setupapi.SetupDiGetDeviceInstallParamsW - -// SetupDiGetDeviceInstallParams function retrieves device installation parameters for a device information set or a particular device information element. -func SetupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (*DevInstallParams, error) { - params := &DevInstallParams{} - params.size = uint32(unsafe.Sizeof(*params)) - - return params, setupDiGetDeviceInstallParams(deviceInfoSet, deviceInfoData, params) -} - -// DeviceInstallParams method retrieves device installation parameters for a device information set or a particular device information element. -func (deviceInfoSet DevInfo) DeviceInstallParams(deviceInfoData *DevInfoData) (*DevInstallParams, error) { - return SetupDiGetDeviceInstallParams(deviceInfoSet, deviceInfoData) -} - -//sys setupDiGetDeviceInstanceId(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, instanceId *uint16, instanceIdSize uint32, instanceIdRequiredSize *uint32) (err error) = setupapi.SetupDiGetDeviceInstanceIdW - -// SetupDiGetDeviceInstanceId function retrieves the instance ID of the device. -func SetupDiGetDeviceInstanceId(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (string, error) { - reqSize := uint32(1024) - for { - buf := make([]uint16, reqSize) - err := setupDiGetDeviceInstanceId(deviceInfoSet, deviceInfoData, &buf[0], uint32(len(buf)), &reqSize) - if err == windows.ERROR_INSUFFICIENT_BUFFER { - continue - } - if err != nil { - return "", err - } - return windows.UTF16ToString(buf), nil - } -} - -// DeviceInstanceID method retrieves the instance ID of the device. -func (deviceInfoSet DevInfo) DeviceInstanceID(deviceInfoData *DevInfoData) (string, error) { - return SetupDiGetDeviceInstanceId(deviceInfoSet, deviceInfoData) -} - -// SetupDiGetClassInstallParams function retrieves class installation parameters for a device information set or a particular device information element. -//sys SetupDiGetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiGetClassInstallParamsW - -// ClassInstallParams method retrieves class installation parameters for a device information set or a particular device information element. -func (deviceInfoSet DevInfo) ClassInstallParams(deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32, requiredSize *uint32) error { - return SetupDiGetClassInstallParams(deviceInfoSet, deviceInfoData, classInstallParams, classInstallParamsSize, requiredSize) -} - -//sys SetupDiSetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) = setupapi.SetupDiSetDeviceInstallParamsW - -// SetDeviceInstallParams member sets device installation parameters for a device information set or a particular device information element. -func (deviceInfoSet DevInfo) SetDeviceInstallParams(deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) error { - return SetupDiSetDeviceInstallParams(deviceInfoSet, deviceInfoData, deviceInstallParams) -} - -// SetupDiSetClassInstallParams function sets or clears class install parameters for a device information set or a particular device information element. -//sys SetupDiSetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32) (err error) = setupapi.SetupDiSetClassInstallParamsW - -// SetClassInstallParams method sets or clears class install parameters for a device information set or a particular device information element. -func (deviceInfoSet DevInfo) SetClassInstallParams(deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32) error { - return SetupDiSetClassInstallParams(deviceInfoSet, deviceInfoData, classInstallParams, classInstallParamsSize) -} - -//sys setupDiClassNameFromGuidEx(classGUID *windows.GUID, className *uint16, classNameSize uint32, requiredSize *uint32, machineName *uint16, reserved uintptr) (err error) = setupapi.SetupDiClassNameFromGuidExW - -// SetupDiClassNameFromGuidEx function retrieves the class name associated with a class GUID. The class can be installed on a local or remote computer. -func SetupDiClassNameFromGuidEx(classGUID *windows.GUID, machineName string) (className string, err error) { - var classNameUTF16 [MAX_CLASS_NAME_LEN]uint16 - - var machineNameUTF16 *uint16 - if machineName != "" { - machineNameUTF16, err = windows.UTF16PtrFromString(machineName) - if err != nil { - return - } - } - - err = setupDiClassNameFromGuidEx(classGUID, &classNameUTF16[0], MAX_CLASS_NAME_LEN, nil, machineNameUTF16, 0) - if err != nil { - return - } - - className = windows.UTF16ToString(classNameUTF16[:]) - return -} - -//sys setupDiClassGuidsFromNameEx(className *uint16, classGuidList *windows.GUID, classGuidListSize uint32, requiredSize *uint32, machineName *uint16, reserved uintptr) (err error) = setupapi.SetupDiClassGuidsFromNameExW - -// SetupDiClassGuidsFromNameEx function retrieves the GUIDs associated with the specified class name. This resulting list contains the classes currently installed on a local or remote computer. -func SetupDiClassGuidsFromNameEx(className string, machineName string) ([]windows.GUID, error) { - classNameUTF16, err := windows.UTF16PtrFromString(className) - if err != nil { - return nil, err - } - - var machineNameUTF16 *uint16 - if machineName != "" { - machineNameUTF16, err = windows.UTF16PtrFromString(machineName) - if err != nil { - return nil, err - } - } - - reqSize := uint32(4) - for { - buf := make([]windows.GUID, reqSize) - err = setupDiClassGuidsFromNameEx(classNameUTF16, &buf[0], uint32(len(buf)), &reqSize, machineNameUTF16, 0) - if err == windows.ERROR_INSUFFICIENT_BUFFER { - continue - } - if err != nil { - return nil, err - } - return buf[:reqSize], nil - } -} - -//sys setupDiGetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiGetSelectedDevice - -// SetupDiGetSelectedDevice function retrieves the selected device information element in a device information set. -func SetupDiGetSelectedDevice(deviceInfoSet DevInfo) (*DevInfoData, error) { - data := &DevInfoData{} - data.size = uint32(unsafe.Sizeof(*data)) - - return data, setupDiGetSelectedDevice(deviceInfoSet, data) -} - -// SelectedDevice method retrieves the selected device information element in a device information set. -func (deviceInfoSet DevInfo) SelectedDevice() (*DevInfoData, error) { - return SetupDiGetSelectedDevice(deviceInfoSet) -} - -// SetupDiSetSelectedDevice function sets a device information element as the selected member of a device information set. This function is typically used by an installation wizard. -//sys SetupDiSetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiSetSelectedDevice - -// SetSelectedDevice method sets a device information element as the selected member of a device information set. This function is typically used by an installation wizard. -func (deviceInfoSet DevInfo) SetSelectedDevice(deviceInfoData *DevInfoData) error { - return SetupDiSetSelectedDevice(deviceInfoSet, deviceInfoData) -} - -//sys cm_Get_Device_Interface_List_Size(len *uint32, interfaceClass *windows.GUID, deviceID *uint16, flags uint32) (ret uint32) = CfgMgr32.CM_Get_Device_Interface_List_SizeW -//sys cm_Get_Device_Interface_List(interfaceClass *windows.GUID, deviceID *uint16, buffer *uint16, bufferLen uint32, flags uint32) (ret uint32) = CfgMgr32.CM_Get_Device_Interface_ListW - -func CM_Get_Device_Interface_List(deviceID string, interfaceClass *windows.GUID, flags uint32) ([]string, error) { - deviceID16, err := windows.UTF16PtrFromString(deviceID) - if err != nil { - return nil, err - } - var buf []uint16 - var buflen uint32 - for { - if ret := cm_Get_Device_Interface_List_Size(&buflen, interfaceClass, deviceID16, flags); ret != CR_SUCCESS { - return nil, fmt.Errorf("CfgMgr error: 0x%x", ret) - } - buf = make([]uint16, buflen) - if ret := cm_Get_Device_Interface_List(interfaceClass, deviceID16, &buf[0], buflen, flags); ret == CR_SUCCESS { - break - } else if ret != CR_BUFFER_SMALL { - return nil, fmt.Errorf("CfgMgr error: 0x%x", ret) - } - } - var interfaces []string - for i := 0; i < len(buf); { - j := i + wcslen(buf[i:]) - if i < j { - interfaces = append(interfaces, windows.UTF16ToString(buf[i:j])) - } - i = j + 1 - } - if interfaces == nil { - return nil, fmt.Errorf("no interfaces found") - } - return interfaces, nil -} diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/types_windows.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/types_windows.go deleted file mode 100644 index 239d80b93c..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/types_windows.go +++ /dev/null @@ -1,568 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package setupapi - -import ( - "strings" - "unsafe" - - "golang.org/x/sys/windows" -) - -const ( - MAX_DEVICE_ID_LEN = 200 - MAX_DEVNODE_ID_LEN = MAX_DEVICE_ID_LEN - MAX_GUID_STRING_LEN = 39 // 38 chars + terminator null - MAX_CLASS_NAME_LEN = 32 - MAX_PROFILE_LEN = 80 - MAX_CONFIG_VALUE = 9999 - MAX_INSTANCE_VALUE = 9999 - CONFIGMG_VERSION = 0x0400 -) - -// -// Define maximum string length constants -// -const ( - ANYSIZE_ARRAY = 1 - LINE_LEN = 256 // Windows 9x-compatible maximum for displayable strings coming from a device INF. - MAX_INF_STRING_LENGTH = 4096 // Actual maximum size of an INF string (including string substitutions). - MAX_INF_SECTION_NAME_LENGTH = 255 // For Windows 9x compatibility, INF section names should be constrained to 32 characters. - MAX_TITLE_LEN = 60 - MAX_INSTRUCTION_LEN = 256 - MAX_LABEL_LEN = 30 - MAX_SERVICE_NAME_LEN = 256 - MAX_SUBTITLE_LEN = 256 -) - -const ( - // SP_MAX_MACHINENAME_LENGTH defines maximum length of a machine name in the format expected by ConfigMgr32 CM_Connect_Machine (i.e., "\\\\MachineName\0"). - SP_MAX_MACHINENAME_LENGTH = windows.MAX_PATH + 3 -) - -// HSPFILEQ is type for setup file queue -type HSPFILEQ uintptr - -// DevInfo holds reference to device information set -type DevInfo windows.Handle - -// DevInfoData is a device information structure (references a device instance that is a member of a device information set) -type DevInfoData struct { - size uint32 - ClassGUID windows.GUID - DevInst uint32 // DEVINST handle - _ uintptr -} - -// DevInfoListDetailData is a structure for detailed information on a device information set (used for SetupDiGetDeviceInfoListDetail which supersedes the functionality of SetupDiGetDeviceInfoListClass). -type DevInfoListDetailData struct { - size uint32 // Warning: unsafe.Sizeof(DevInfoListDetailData) > sizeof(SP_DEVINFO_LIST_DETAIL_DATA) when GOARCH == 386 => use sizeofDevInfoListDetailData const. - ClassGUID windows.GUID - RemoteMachineHandle windows.Handle - remoteMachineName [SP_MAX_MACHINENAME_LENGTH]uint16 -} - -func (data *DevInfoListDetailData) RemoteMachineName() string { - return windows.UTF16ToString(data.remoteMachineName[:]) -} - -func (data *DevInfoListDetailData) SetRemoteMachineName(remoteMachineName string) error { - str, err := windows.UTF16FromString(remoteMachineName) - if err != nil { - return err - } - copy(data.remoteMachineName[:], str) - return nil -} - -// DI_FUNCTION is function type for device installer -type DI_FUNCTION uint32 - -const ( - DIF_SELECTDEVICE DI_FUNCTION = 0x00000001 - DIF_INSTALLDEVICE DI_FUNCTION = 0x00000002 - DIF_ASSIGNRESOURCES DI_FUNCTION = 0x00000003 - DIF_PROPERTIES DI_FUNCTION = 0x00000004 - DIF_REMOVE DI_FUNCTION = 0x00000005 - DIF_FIRSTTIMESETUP DI_FUNCTION = 0x00000006 - DIF_FOUNDDEVICE DI_FUNCTION = 0x00000007 - DIF_SELECTCLASSDRIVERS DI_FUNCTION = 0x00000008 - DIF_VALIDATECLASSDRIVERS DI_FUNCTION = 0x00000009 - DIF_INSTALLCLASSDRIVERS DI_FUNCTION = 0x0000000A - DIF_CALCDISKSPACE DI_FUNCTION = 0x0000000B - DIF_DESTROYPRIVATEDATA DI_FUNCTION = 0x0000000C - DIF_VALIDATEDRIVER DI_FUNCTION = 0x0000000D - DIF_DETECT DI_FUNCTION = 0x0000000F - DIF_INSTALLWIZARD DI_FUNCTION = 0x00000010 - DIF_DESTROYWIZARDDATA DI_FUNCTION = 0x00000011 - DIF_PROPERTYCHANGE DI_FUNCTION = 0x00000012 - DIF_ENABLECLASS DI_FUNCTION = 0x00000013 - DIF_DETECTVERIFY DI_FUNCTION = 0x00000014 - DIF_INSTALLDEVICEFILES DI_FUNCTION = 0x00000015 - DIF_UNREMOVE DI_FUNCTION = 0x00000016 - DIF_SELECTBESTCOMPATDRV DI_FUNCTION = 0x00000017 - DIF_ALLOW_INSTALL DI_FUNCTION = 0x00000018 - DIF_REGISTERDEVICE DI_FUNCTION = 0x00000019 - DIF_NEWDEVICEWIZARD_PRESELECT DI_FUNCTION = 0x0000001A - DIF_NEWDEVICEWIZARD_SELECT DI_FUNCTION = 0x0000001B - DIF_NEWDEVICEWIZARD_PREANALYZE DI_FUNCTION = 0x0000001C - DIF_NEWDEVICEWIZARD_POSTANALYZE DI_FUNCTION = 0x0000001D - DIF_NEWDEVICEWIZARD_FINISHINSTALL DI_FUNCTION = 0x0000001E - DIF_INSTALLINTERFACES DI_FUNCTION = 0x00000020 - DIF_DETECTCANCEL DI_FUNCTION = 0x00000021 - DIF_REGISTER_COINSTALLERS DI_FUNCTION = 0x00000022 - DIF_ADDPROPERTYPAGE_ADVANCED DI_FUNCTION = 0x00000023 - DIF_ADDPROPERTYPAGE_BASIC DI_FUNCTION = 0x00000024 - DIF_TROUBLESHOOTER DI_FUNCTION = 0x00000026 - DIF_POWERMESSAGEWAKE DI_FUNCTION = 0x00000027 - DIF_ADDREMOTEPROPERTYPAGE_ADVANCED DI_FUNCTION = 0x00000028 - DIF_UPDATEDRIVER_UI DI_FUNCTION = 0x00000029 - DIF_FINISHINSTALL_ACTION DI_FUNCTION = 0x0000002A -) - -// DevInstallParams is device installation parameters structure (associated with a particular device information element, or globally with a device information set) -type DevInstallParams struct { - size uint32 - Flags DI_FLAGS - FlagsEx DI_FLAGSEX - hwndParent uintptr - InstallMsgHandler uintptr - InstallMsgHandlerContext uintptr - FileQueue HSPFILEQ - _ uintptr - _ uint32 - driverPath [windows.MAX_PATH]uint16 -} - -func (params *DevInstallParams) DriverPath() string { - return windows.UTF16ToString(params.driverPath[:]) -} - -func (params *DevInstallParams) SetDriverPath(driverPath string) error { - str, err := windows.UTF16FromString(driverPath) - if err != nil { - return err - } - copy(params.driverPath[:], str) - return nil -} - -// DI_FLAGS is SP_DEVINSTALL_PARAMS.Flags values -type DI_FLAGS uint32 - -const ( - // Flags for choosing a device - DI_SHOWOEM DI_FLAGS = 0x00000001 // support Other... button - DI_SHOWCOMPAT DI_FLAGS = 0x00000002 // show compatibility list - DI_SHOWCLASS DI_FLAGS = 0x00000004 // show class list - DI_SHOWALL DI_FLAGS = 0x00000007 // both class & compat list shown - DI_NOVCP DI_FLAGS = 0x00000008 // don't create a new copy queue--use caller-supplied FileQueue - DI_DIDCOMPAT DI_FLAGS = 0x00000010 // Searched for compatible devices - DI_DIDCLASS DI_FLAGS = 0x00000020 // Searched for class devices - DI_AUTOASSIGNRES DI_FLAGS = 0x00000040 // No UI for resources if possible - - // Flags returned by DiInstallDevice to indicate need to reboot/restart - DI_NEEDRESTART DI_FLAGS = 0x00000080 // Reboot required to take effect - DI_NEEDREBOOT DI_FLAGS = 0x00000100 // "" - - // Flags for device installation - DI_NOBROWSE DI_FLAGS = 0x00000200 // no Browse... in InsertDisk - - // Flags set by DiBuildDriverInfoList - DI_MULTMFGS DI_FLAGS = 0x00000400 // Set if multiple manufacturers in class driver list - - // Flag indicates that device is disabled - DI_DISABLED DI_FLAGS = 0x00000800 // Set if device disabled - - // Flags for Device/Class Properties - DI_GENERALPAGE_ADDED DI_FLAGS = 0x00001000 - DI_RESOURCEPAGE_ADDED DI_FLAGS = 0x00002000 - - // Flag to indicate the setting properties for this Device (or class) caused a change so the Dev Mgr UI probably needs to be updated. - DI_PROPERTIES_CHANGE DI_FLAGS = 0x00004000 - - // Flag to indicate that the sorting from the INF file should be used. - DI_INF_IS_SORTED DI_FLAGS = 0x00008000 - - // Flag to indicate that only the the INF specified by SP_DEVINSTALL_PARAMS.DriverPath should be searched. - DI_ENUMSINGLEINF DI_FLAGS = 0x00010000 - - // Flag that prevents ConfigMgr from removing/re-enumerating devices during device - // registration, installation, and deletion. - DI_DONOTCALLCONFIGMG DI_FLAGS = 0x00020000 - - // The following flag can be used to install a device disabled - DI_INSTALLDISABLED DI_FLAGS = 0x00040000 - - // Flag that causes SetupDiBuildDriverInfoList to build a device's compatible driver - // list from its existing class driver list, instead of the normal INF search. - DI_COMPAT_FROM_CLASS DI_FLAGS = 0x00080000 - - // This flag is set if the Class Install params should be used. - DI_CLASSINSTALLPARAMS DI_FLAGS = 0x00100000 - - // This flag is set if the caller of DiCallClassInstaller does NOT want the internal default action performed if the Class installer returns ERROR_DI_DO_DEFAULT. - DI_NODI_DEFAULTACTION DI_FLAGS = 0x00200000 - - // Flags for device installation - DI_QUIETINSTALL DI_FLAGS = 0x00800000 // don't confuse the user with questions or excess info - DI_NOFILECOPY DI_FLAGS = 0x01000000 // No file Copy necessary - DI_FORCECOPY DI_FLAGS = 0x02000000 // Force files to be copied from install path - DI_DRIVERPAGE_ADDED DI_FLAGS = 0x04000000 // Prop provider added Driver page. - DI_USECI_SELECTSTRINGS DI_FLAGS = 0x08000000 // Use Class Installer Provided strings in the Select Device Dlg - DI_OVERRIDE_INFFLAGS DI_FLAGS = 0x10000000 // Override INF flags - DI_PROPS_NOCHANGEUSAGE DI_FLAGS = 0x20000000 // No Enable/Disable in General Props - - DI_NOSELECTICONS DI_FLAGS = 0x40000000 // No small icons in select device dialogs - - DI_NOWRITE_IDS DI_FLAGS = 0x80000000 // Don't write HW & Compat IDs on install -) - -// DI_FLAGSEX is SP_DEVINSTALL_PARAMS.FlagsEx values -type DI_FLAGSEX uint32 - -const ( - DI_FLAGSEX_CI_FAILED DI_FLAGSEX = 0x00000004 // Failed to Load/Call class installer - DI_FLAGSEX_FINISHINSTALL_ACTION DI_FLAGSEX = 0x00000008 // Class/co-installer wants to get a DIF_FINISH_INSTALL action in client context. - DI_FLAGSEX_DIDINFOLIST DI_FLAGSEX = 0x00000010 // Did the Class Info List - DI_FLAGSEX_DIDCOMPATINFO DI_FLAGSEX = 0x00000020 // Did the Compat Info List - DI_FLAGSEX_FILTERCLASSES DI_FLAGSEX = 0x00000040 - DI_FLAGSEX_SETFAILEDINSTALL DI_FLAGSEX = 0x00000080 - DI_FLAGSEX_DEVICECHANGE DI_FLAGSEX = 0x00000100 - DI_FLAGSEX_ALWAYSWRITEIDS DI_FLAGSEX = 0x00000200 - DI_FLAGSEX_PROPCHANGE_PENDING DI_FLAGSEX = 0x00000400 // One or more device property sheets have had changes made to them, and need to have a DIF_PROPERTYCHANGE occur. - DI_FLAGSEX_ALLOWEXCLUDEDDRVS DI_FLAGSEX = 0x00000800 - DI_FLAGSEX_NOUIONQUERYREMOVE DI_FLAGSEX = 0x00001000 - DI_FLAGSEX_USECLASSFORCOMPAT DI_FLAGSEX = 0x00002000 // Use the device's class when building compat drv list. (Ignored if DI_COMPAT_FROM_CLASS flag is specified.) - DI_FLAGSEX_NO_DRVREG_MODIFY DI_FLAGSEX = 0x00008000 // Don't run AddReg and DelReg for device's software (driver) key. - DI_FLAGSEX_IN_SYSTEM_SETUP DI_FLAGSEX = 0x00010000 // Installation is occurring during initial system setup. - DI_FLAGSEX_INET_DRIVER DI_FLAGSEX = 0x00020000 // Driver came from Windows Update - DI_FLAGSEX_APPENDDRIVERLIST DI_FLAGSEX = 0x00040000 // Cause SetupDiBuildDriverInfoList to append a new driver list to an existing list. - DI_FLAGSEX_PREINSTALLBACKUP DI_FLAGSEX = 0x00080000 // not used - DI_FLAGSEX_BACKUPONREPLACE DI_FLAGSEX = 0x00100000 // not used - DI_FLAGSEX_DRIVERLIST_FROM_URL DI_FLAGSEX = 0x00200000 // build driver list from INF(s) retrieved from URL specified in SP_DEVINSTALL_PARAMS.DriverPath (empty string means Windows Update website) - DI_FLAGSEX_EXCLUDE_OLD_INET_DRIVERS DI_FLAGSEX = 0x00800000 // Don't include old Internet drivers when building a driver list. Ignored on Windows Vista and later. - DI_FLAGSEX_POWERPAGE_ADDED DI_FLAGSEX = 0x01000000 // class installer added their own power page - DI_FLAGSEX_FILTERSIMILARDRIVERS DI_FLAGSEX = 0x02000000 // only include similar drivers in class list - DI_FLAGSEX_INSTALLEDDRIVER DI_FLAGSEX = 0x04000000 // only add the installed driver to the class or compat driver list. Used in calls to SetupDiBuildDriverInfoList - DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE DI_FLAGSEX = 0x08000000 // Don't remove identical driver nodes from the class list - DI_FLAGSEX_ALTPLATFORM_DRVSEARCH DI_FLAGSEX = 0x10000000 // Build driver list based on alternate platform information specified in associated file queue - DI_FLAGSEX_RESTART_DEVICE_ONLY DI_FLAGSEX = 0x20000000 // only restart the device drivers are being installed on as opposed to restarting all devices using those drivers. - DI_FLAGSEX_RECURSIVESEARCH DI_FLAGSEX = 0x40000000 // Tell SetupDiBuildDriverInfoList to do a recursive search - DI_FLAGSEX_SEARCH_PUBLISHED_INFS DI_FLAGSEX = 0x80000000 // Tell SetupDiBuildDriverInfoList to do a "published INF" search -) - -// ClassInstallHeader is the first member of any class install parameters structure. It contains the device installation request code that defines the format of the rest of the install parameters structure. -type ClassInstallHeader struct { - size uint32 - InstallFunction DI_FUNCTION -} - -func MakeClassInstallHeader(installFunction DI_FUNCTION) *ClassInstallHeader { - hdr := &ClassInstallHeader{InstallFunction: installFunction} - hdr.size = uint32(unsafe.Sizeof(*hdr)) - return hdr -} - -// DICS_STATE specifies values indicating a change in a device's state -type DICS_STATE uint32 - -const ( - DICS_ENABLE DICS_STATE = 0x00000001 // The device is being enabled. - DICS_DISABLE DICS_STATE = 0x00000002 // The device is being disabled. - DICS_PROPCHANGE DICS_STATE = 0x00000003 // The properties of the device have changed. - DICS_START DICS_STATE = 0x00000004 // The device is being started (if the request is for the currently active hardware profile). - DICS_STOP DICS_STATE = 0x00000005 // The device is being stopped. The driver stack will be unloaded and the CSCONFIGFLAG_DO_NOT_START flag will be set for the device. -) - -// DICS_FLAG specifies the scope of a device property change -type DICS_FLAG uint32 - -const ( - DICS_FLAG_GLOBAL DICS_FLAG = 0x00000001 // make change in all hardware profiles - DICS_FLAG_CONFIGSPECIFIC DICS_FLAG = 0x00000002 // make change in specified profile only - DICS_FLAG_CONFIGGENERAL DICS_FLAG = 0x00000004 // 1 or more hardware profile-specific changes to follow (obsolete) -) - -// PropChangeParams is a structure corresponding to a DIF_PROPERTYCHANGE install function. -type PropChangeParams struct { - ClassInstallHeader ClassInstallHeader - StateChange DICS_STATE - Scope DICS_FLAG - HwProfile uint32 -} - -// DI_REMOVEDEVICE specifies the scope of the device removal -type DI_REMOVEDEVICE uint32 - -const ( - DI_REMOVEDEVICE_GLOBAL DI_REMOVEDEVICE = 0x00000001 // Make this change in all hardware profiles. Remove information about the device from the registry. - DI_REMOVEDEVICE_CONFIGSPECIFIC DI_REMOVEDEVICE = 0x00000002 // Make this change to only the hardware profile specified by HwProfile. this flag only applies to root-enumerated devices. When Windows removes the device from the last hardware profile in which it was configured, Windows performs a global removal. -) - -// RemoveDeviceParams is a structure corresponding to a DIF_REMOVE install function. -type RemoveDeviceParams struct { - ClassInstallHeader ClassInstallHeader - Scope DI_REMOVEDEVICE - HwProfile uint32 -} - -// DrvInfoData is driver information structure (member of a driver info list that may be associated with a particular device instance, or (globally) with a device information set) -type DrvInfoData struct { - size uint32 - DriverType uint32 - _ uintptr - description [LINE_LEN]uint16 - mfgName [LINE_LEN]uint16 - providerName [LINE_LEN]uint16 - DriverDate windows.Filetime - DriverVersion uint64 -} - -func (data *DrvInfoData) Description() string { - return windows.UTF16ToString(data.description[:]) -} - -func (data *DrvInfoData) SetDescription(description string) error { - str, err := windows.UTF16FromString(description) - if err != nil { - return err - } - copy(data.description[:], str) - return nil -} - -func (data *DrvInfoData) MfgName() string { - return windows.UTF16ToString(data.mfgName[:]) -} - -func (data *DrvInfoData) SetMfgName(mfgName string) error { - str, err := windows.UTF16FromString(mfgName) - if err != nil { - return err - } - copy(data.mfgName[:], str) - return nil -} - -func (data *DrvInfoData) ProviderName() string { - return windows.UTF16ToString(data.providerName[:]) -} - -func (data *DrvInfoData) SetProviderName(providerName string) error { - str, err := windows.UTF16FromString(providerName) - if err != nil { - return err - } - copy(data.providerName[:], str) - return nil -} - -// IsNewer method returns true if DrvInfoData date and version is newer than supplied parameters. -func (data *DrvInfoData) IsNewer(driverDate windows.Filetime, driverVersion uint64) bool { - if data.DriverDate.HighDateTime > driverDate.HighDateTime { - return true - } - if data.DriverDate.HighDateTime < driverDate.HighDateTime { - return false - } - - if data.DriverDate.LowDateTime > driverDate.LowDateTime { - return true - } - if data.DriverDate.LowDateTime < driverDate.LowDateTime { - return false - } - - if data.DriverVersion > driverVersion { - return true - } - if data.DriverVersion < driverVersion { - return false - } - - return false -} - -// DrvInfoDetailData is driver information details structure (provides detailed information about a particular driver information structure) -type DrvInfoDetailData struct { - size uint32 // Warning: unsafe.Sizeof(DrvInfoDetailData) > sizeof(SP_DRVINFO_DETAIL_DATA) when GOARCH == 386 => use sizeofDrvInfoDetailData const. - InfDate windows.Filetime - compatIDsOffset uint32 - compatIDsLength uint32 - _ uintptr - sectionName [LINE_LEN]uint16 - infFileName [windows.MAX_PATH]uint16 - drvDescription [LINE_LEN]uint16 - hardwareID [ANYSIZE_ARRAY]uint16 -} - -func (data *DrvInfoDetailData) SectionName() string { - return windows.UTF16ToString(data.sectionName[:]) -} - -func (data *DrvInfoDetailData) InfFileName() string { - return windows.UTF16ToString(data.infFileName[:]) -} - -func (data *DrvInfoDetailData) DrvDescription() string { - return windows.UTF16ToString(data.drvDescription[:]) -} - -func (data *DrvInfoDetailData) HardwareID() string { - if data.compatIDsOffset > 1 { - bufW := data.getBuf() - return windows.UTF16ToString(bufW[:wcslen(bufW)]) - } - - return "" -} - -func (data *DrvInfoDetailData) CompatIDs() []string { - a := make([]string, 0) - - if data.compatIDsLength > 0 { - bufW := data.getBuf() - bufW = bufW[data.compatIDsOffset : data.compatIDsOffset+data.compatIDsLength] - for i := 0; i < len(bufW); { - j := i + wcslen(bufW[i:]) - if i < j { - a = append(a, windows.UTF16ToString(bufW[i:j])) - } - i = j + 1 - } - } - - return a -} - -func (data *DrvInfoDetailData) getBuf() []uint16 { - len := (data.size - uint32(unsafe.Offsetof(data.hardwareID))) / 2 - sl := struct { - addr *uint16 - len int - cap int - }{&data.hardwareID[0], int(len), int(len)} - return *(*[]uint16)(unsafe.Pointer(&sl)) -} - -// IsCompatible method tests if given hardware ID matches the driver or is listed on the compatible ID list. -func (data *DrvInfoDetailData) IsCompatible(hwid string) bool { - hwidLC := strings.ToLower(hwid) - if strings.ToLower(data.HardwareID()) == hwidLC { - return true - } - a := data.CompatIDs() - for i := range a { - if strings.ToLower(a[i]) == hwidLC { - return true - } - } - - return false -} - -// DICD flags control SetupDiCreateDeviceInfo -type DICD uint32 - -const ( - DICD_GENERATE_ID DICD = 0x00000001 - DICD_INHERIT_CLASSDRVS DICD = 0x00000002 -) - -// -// SPDIT flags to distinguish between class drivers and -// device drivers. -// (Passed in 'DriverType' parameter of driver information list APIs) -// -type SPDIT uint32 - -const ( - SPDIT_NODRIVER SPDIT = 0x00000000 - SPDIT_CLASSDRIVER SPDIT = 0x00000001 - SPDIT_COMPATDRIVER SPDIT = 0x00000002 -) - -// DIGCF flags control what is included in the device information set built by SetupDiGetClassDevs -type DIGCF uint32 - -const ( - DIGCF_DEFAULT DIGCF = 0x00000001 // only valid with DIGCF_DEVICEINTERFACE - DIGCF_PRESENT DIGCF = 0x00000002 - DIGCF_ALLCLASSES DIGCF = 0x00000004 - DIGCF_PROFILE DIGCF = 0x00000008 - DIGCF_DEVICEINTERFACE DIGCF = 0x00000010 -) - -// DIREG specifies values for SetupDiCreateDevRegKey, SetupDiOpenDevRegKey, and SetupDiDeleteDevRegKey. -type DIREG uint32 - -const ( - DIREG_DEV DIREG = 0x00000001 // Open/Create/Delete device key - DIREG_DRV DIREG = 0x00000002 // Open/Create/Delete driver key - DIREG_BOTH DIREG = 0x00000004 // Delete both driver and Device key -) - -// -// SPDRP specifies device registry property codes -// (Codes marked as read-only (R) may only be used for -// SetupDiGetDeviceRegistryProperty) -// -// These values should cover the same set of registry properties -// as defined by the CM_DRP codes in cfgmgr32.h. -// -// Note that SPDRP codes are zero based while CM_DRP codes are one based! -// -type SPDRP uint32 - -const ( - SPDRP_DEVICEDESC SPDRP = 0x00000000 // DeviceDesc (R/W) - SPDRP_HARDWAREID SPDRP = 0x00000001 // HardwareID (R/W) - SPDRP_COMPATIBLEIDS SPDRP = 0x00000002 // CompatibleIDs (R/W) - SPDRP_SERVICE SPDRP = 0x00000004 // Service (R/W) - SPDRP_CLASS SPDRP = 0x00000007 // Class (R--tied to ClassGUID) - SPDRP_CLASSGUID SPDRP = 0x00000008 // ClassGUID (R/W) - SPDRP_DRIVER SPDRP = 0x00000009 // Driver (R/W) - SPDRP_CONFIGFLAGS SPDRP = 0x0000000A // ConfigFlags (R/W) - SPDRP_MFG SPDRP = 0x0000000B // Mfg (R/W) - SPDRP_FRIENDLYNAME SPDRP = 0x0000000C // FriendlyName (R/W) - SPDRP_LOCATION_INFORMATION SPDRP = 0x0000000D // LocationInformation (R/W) - SPDRP_PHYSICAL_DEVICE_OBJECT_NAME SPDRP = 0x0000000E // PhysicalDeviceObjectName (R) - SPDRP_CAPABILITIES SPDRP = 0x0000000F // Capabilities (R) - SPDRP_UI_NUMBER SPDRP = 0x00000010 // UiNumber (R) - SPDRP_UPPERFILTERS SPDRP = 0x00000011 // UpperFilters (R/W) - SPDRP_LOWERFILTERS SPDRP = 0x00000012 // LowerFilters (R/W) - SPDRP_BUSTYPEGUID SPDRP = 0x00000013 // BusTypeGUID (R) - SPDRP_LEGACYBUSTYPE SPDRP = 0x00000014 // LegacyBusType (R) - SPDRP_BUSNUMBER SPDRP = 0x00000015 // BusNumber (R) - SPDRP_ENUMERATOR_NAME SPDRP = 0x00000016 // Enumerator Name (R) - SPDRP_SECURITY SPDRP = 0x00000017 // Security (R/W, binary form) - SPDRP_SECURITY_SDS SPDRP = 0x00000018 // Security (W, SDS form) - SPDRP_DEVTYPE SPDRP = 0x00000019 // Device Type (R/W) - SPDRP_EXCLUSIVE SPDRP = 0x0000001A // Device is exclusive-access (R/W) - SPDRP_CHARACTERISTICS SPDRP = 0x0000001B // Device Characteristics (R/W) - SPDRP_ADDRESS SPDRP = 0x0000001C // Device Address (R) - SPDRP_UI_NUMBER_DESC_FORMAT SPDRP = 0x0000001D // UiNumberDescFormat (R/W) - SPDRP_DEVICE_POWER_DATA SPDRP = 0x0000001E // Device Power Data (R) - SPDRP_REMOVAL_POLICY SPDRP = 0x0000001F // Removal Policy (R) - SPDRP_REMOVAL_POLICY_HW_DEFAULT SPDRP = 0x00000020 // Hardware Removal Policy (R) - SPDRP_REMOVAL_POLICY_OVERRIDE SPDRP = 0x00000021 // Removal Policy Override (RW) - SPDRP_INSTALL_STATE SPDRP = 0x00000022 // Device Install State (R) - SPDRP_LOCATION_PATHS SPDRP = 0x00000023 // Device Location Paths (R) - SPDRP_BASE_CONTAINERID SPDRP = 0x00000024 // Base ContainerID (R) - - SPDRP_MAXIMUM_PROPERTY SPDRP = 0x00000025 // Upper bound on ordinals -) - -const ( - CR_SUCCESS = 0x0 - CR_BUFFER_SMALL = 0x1a -) - -const ( - CM_GET_DEVICE_INTERFACE_LIST_PRESENT = 0 // only currently 'live' device interfaces - CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES = 1 // all registered device interfaces, live or not -) diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/types_windows_386.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/types_windows_386.go deleted file mode 100644 index 132f9214da..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/types_windows_386.go +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package setupapi - -const ( - sizeofDevInfoListDetailData uint32 = 550 - sizeofDrvInfoDetailData uint32 = 1570 -) diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/types_windows_amd64.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/types_windows_amd64.go deleted file mode 100644 index d4dd65ca30..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/types_windows_amd64.go +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package setupapi - -const ( - sizeofDevInfoListDetailData uint32 = 560 - sizeofDrvInfoDetailData uint32 = 1584 -) diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/zsetupapi_windows.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/zsetupapi_windows.go deleted file mode 100644 index 375862da4b..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/setupapi/zsetupapi_windows.go +++ /dev/null @@ -1,398 +0,0 @@ -// Code generated by 'go generate'; DO NOT EDIT. - -package setupapi - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -var _ unsafe.Pointer - -// Do the interface allocations only once for common -// Errno values. -const ( - errnoERROR_IO_PENDING = 997 -) - -var ( - errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) -) - -// errnoErr returns common boxed Errno values, to prevent -// allocations at runtime. -func errnoErr(e syscall.Errno) error { - switch e { - case 0: - return nil - case errnoERROR_IO_PENDING: - return errERROR_IO_PENDING - } - // TODO: add more here, after collecting data on the common - // error values see on Windows. (perhaps when running - // all.bat?) - return e -} - -var ( - modsetupapi = windows.NewLazySystemDLL("setupapi.dll") - modCfgMgr32 = windows.NewLazySystemDLL("CfgMgr32.dll") - - procSetupDiCreateDeviceInfoListExW = modsetupapi.NewProc("SetupDiCreateDeviceInfoListExW") - procSetupDiGetDeviceInfoListDetailW = modsetupapi.NewProc("SetupDiGetDeviceInfoListDetailW") - procSetupDiCreateDeviceInfoW = modsetupapi.NewProc("SetupDiCreateDeviceInfoW") - procSetupDiEnumDeviceInfo = modsetupapi.NewProc("SetupDiEnumDeviceInfo") - procSetupDiDestroyDeviceInfoList = modsetupapi.NewProc("SetupDiDestroyDeviceInfoList") - procSetupDiBuildDriverInfoList = modsetupapi.NewProc("SetupDiBuildDriverInfoList") - procSetupDiCancelDriverInfoSearch = modsetupapi.NewProc("SetupDiCancelDriverInfoSearch") - procSetupDiEnumDriverInfoW = modsetupapi.NewProc("SetupDiEnumDriverInfoW") - procSetupDiGetSelectedDriverW = modsetupapi.NewProc("SetupDiGetSelectedDriverW") - procSetupDiSetSelectedDriverW = modsetupapi.NewProc("SetupDiSetSelectedDriverW") - procSetupDiGetDriverInfoDetailW = modsetupapi.NewProc("SetupDiGetDriverInfoDetailW") - procSetupDiDestroyDriverInfoList = modsetupapi.NewProc("SetupDiDestroyDriverInfoList") - procSetupDiGetClassDevsExW = modsetupapi.NewProc("SetupDiGetClassDevsExW") - procSetupDiCallClassInstaller = modsetupapi.NewProc("SetupDiCallClassInstaller") - procSetupDiOpenDevRegKey = modsetupapi.NewProc("SetupDiOpenDevRegKey") - procSetupDiGetDeviceRegistryPropertyW = modsetupapi.NewProc("SetupDiGetDeviceRegistryPropertyW") - procSetupDiSetDeviceRegistryPropertyW = modsetupapi.NewProc("SetupDiSetDeviceRegistryPropertyW") - procSetupDiGetDeviceInstallParamsW = modsetupapi.NewProc("SetupDiGetDeviceInstallParamsW") - procSetupDiGetDeviceInstanceIdW = modsetupapi.NewProc("SetupDiGetDeviceInstanceIdW") - procSetupDiGetClassInstallParamsW = modsetupapi.NewProc("SetupDiGetClassInstallParamsW") - procSetupDiSetDeviceInstallParamsW = modsetupapi.NewProc("SetupDiSetDeviceInstallParamsW") - procSetupDiSetClassInstallParamsW = modsetupapi.NewProc("SetupDiSetClassInstallParamsW") - procSetupDiClassNameFromGuidExW = modsetupapi.NewProc("SetupDiClassNameFromGuidExW") - procSetupDiClassGuidsFromNameExW = modsetupapi.NewProc("SetupDiClassGuidsFromNameExW") - procSetupDiGetSelectedDevice = modsetupapi.NewProc("SetupDiGetSelectedDevice") - procSetupDiSetSelectedDevice = modsetupapi.NewProc("SetupDiSetSelectedDevice") - procCM_Get_Device_Interface_List_SizeW = modCfgMgr32.NewProc("CM_Get_Device_Interface_List_SizeW") - procCM_Get_Device_Interface_ListW = modCfgMgr32.NewProc("CM_Get_Device_Interface_ListW") -) - -func setupDiCreateDeviceInfoListEx(classGUID *windows.GUID, hwndParent uintptr, machineName *uint16, reserved uintptr) (handle DevInfo, err error) { - r0, _, e1 := syscall.Syscall6(procSetupDiCreateDeviceInfoListExW.Addr(), 4, uintptr(unsafe.Pointer(classGUID)), uintptr(hwndParent), uintptr(unsafe.Pointer(machineName)), uintptr(reserved), 0, 0) - handle = DevInfo(r0) - if handle == DevInfo(windows.InvalidHandle) { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiGetDeviceInfoListDetail(deviceInfoSet DevInfo, deviceInfoSetDetailData *DevInfoListDetailData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiGetDeviceInfoListDetailW.Addr(), 2, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoSetDetailData)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiCreateDeviceInfo(deviceInfoSet DevInfo, DeviceName *uint16, classGUID *windows.GUID, DeviceDescription *uint16, hwndParent uintptr, CreationFlags DICD, deviceInfoData *DevInfoData) (err error) { - r1, _, e1 := syscall.Syscall9(procSetupDiCreateDeviceInfoW.Addr(), 7, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(DeviceName)), uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(DeviceDescription)), uintptr(hwndParent), uintptr(CreationFlags), uintptr(unsafe.Pointer(deviceInfoData)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiEnumDeviceInfo(deviceInfoSet DevInfo, memberIndex uint32, deviceInfoData *DevInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiEnumDeviceInfo.Addr(), 3, uintptr(deviceInfoSet), uintptr(memberIndex), uintptr(unsafe.Pointer(deviceInfoData))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetupDiDestroyDeviceInfoList(deviceInfoSet DevInfo) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiDestroyDeviceInfoList.Addr(), 1, uintptr(deviceInfoSet), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetupDiBuildDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiBuildDriverInfoList.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetupDiCancelDriverInfoSearch(deviceInfoSet DevInfo) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiCancelDriverInfoSearch.Addr(), 1, uintptr(deviceInfoSet), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiEnumDriverInfo(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT, memberIndex uint32, driverInfoData *DrvInfoData) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiEnumDriverInfoW.Addr(), 5, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType), uintptr(memberIndex), uintptr(unsafe.Pointer(driverInfoData)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiGetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiGetSelectedDriverW.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetupDiSetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiSetSelectedDriverW.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData, driverInfoDetailData *DrvInfoDetailData, driverInfoDetailDataSize uint32, requiredSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiGetDriverInfoDetailW.Addr(), 6, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData)), uintptr(unsafe.Pointer(driverInfoDetailData)), uintptr(driverInfoDetailDataSize), uintptr(unsafe.Pointer(requiredSize))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetupDiDestroyDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiDestroyDriverInfoList.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiGetClassDevsEx(classGUID *windows.GUID, Enumerator *uint16, hwndParent uintptr, Flags DIGCF, deviceInfoSet DevInfo, machineName *uint16, reserved uintptr) (handle DevInfo, err error) { - r0, _, e1 := syscall.Syscall9(procSetupDiGetClassDevsExW.Addr(), 7, uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(Enumerator)), uintptr(hwndParent), uintptr(Flags), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(machineName)), uintptr(reserved), 0, 0) - handle = DevInfo(r0) - if handle == DevInfo(windows.InvalidHandle) { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetupDiCallClassInstaller(installFunction DI_FUNCTION, deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiCallClassInstaller.Addr(), 3, uintptr(installFunction), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiOpenDevRegKey(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, Scope DICS_FLAG, HwProfile uint32, KeyType DIREG, samDesired uint32) (key windows.Handle, err error) { - r0, _, e1 := syscall.Syscall6(procSetupDiOpenDevRegKey.Addr(), 6, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(Scope), uintptr(HwProfile), uintptr(KeyType), uintptr(samDesired)) - key = windows.Handle(r0) - if key == windows.InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyRegDataType *uint32, propertyBuffer *byte, propertyBufferSize uint32, requiredSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procSetupDiGetDeviceRegistryPropertyW.Addr(), 7, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(property), uintptr(unsafe.Pointer(propertyRegDataType)), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize), uintptr(unsafe.Pointer(requiredSize)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiSetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyBuffer *byte, propertyBufferSize uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiSetDeviceRegistryPropertyW.Addr(), 5, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(property), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiGetDeviceInstallParamsW.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(deviceInstallParams))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiGetDeviceInstanceId(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, instanceId *uint16, instanceIdSize uint32, instanceIdRequiredSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiGetDeviceInstanceIdW.Addr(), 5, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(instanceId)), uintptr(instanceIdSize), uintptr(unsafe.Pointer(instanceIdRequiredSize)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetupDiGetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32, requiredSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiGetClassInstallParamsW.Addr(), 5, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(classInstallParams)), uintptr(classInstallParamsSize), uintptr(unsafe.Pointer(requiredSize)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetupDiSetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiSetDeviceInstallParamsW.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(deviceInstallParams))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetupDiSetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiSetClassInstallParamsW.Addr(), 4, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(classInstallParams)), uintptr(classInstallParamsSize), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiClassNameFromGuidEx(classGUID *windows.GUID, className *uint16, classNameSize uint32, requiredSize *uint32, machineName *uint16, reserved uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiClassNameFromGuidExW.Addr(), 6, uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(className)), uintptr(classNameSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiClassGuidsFromNameEx(className *uint16, classGuidList *windows.GUID, classGuidListSize uint32, requiredSize *uint32, machineName *uint16, reserved uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiClassGuidsFromNameExW.Addr(), 6, uintptr(unsafe.Pointer(className)), uintptr(unsafe.Pointer(classGuidList)), uintptr(classGuidListSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiGetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiGetSelectedDevice.Addr(), 2, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func SetupDiSetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiSetSelectedDevice.Addr(), 2, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func cm_Get_Device_Interface_List_Size(len *uint32, interfaceClass *windows.GUID, deviceID *uint16, flags uint32) (ret uint32) { - r0, _, _ := syscall.Syscall6(procCM_Get_Device_Interface_List_SizeW.Addr(), 4, uintptr(unsafe.Pointer(len)), uintptr(unsafe.Pointer(interfaceClass)), uintptr(unsafe.Pointer(deviceID)), uintptr(flags), 0, 0) - ret = uint32(r0) - return -} - -func cm_Get_Device_Interface_List(interfaceClass *windows.GUID, deviceID *uint16, buffer *uint16, bufferLen uint32, flags uint32) (ret uint32) { - r0, _, _ := syscall.Syscall6(procCM_Get_Device_Interface_ListW.Addr(), 5, uintptr(unsafe.Pointer(interfaceClass)), uintptr(unsafe.Pointer(deviceID)), uintptr(unsafe.Pointer(buffer)), uintptr(bufferLen), uintptr(flags), 0) - ret = uint32(r0) - return -} diff --git a/vendor/golang.zx2c4.com/wireguard/tun/wintun/wintun_windows.go b/vendor/golang.zx2c4.com/wireguard/tun/wintun/wintun_windows.go deleted file mode 100644 index 4c12d97742..0000000000 --- a/vendor/golang.zx2c4.com/wireguard/tun/wintun/wintun_windows.go +++ /dev/null @@ -1,803 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package wintun - -import ( - "errors" - "fmt" - "strings" - "time" - "unsafe" - - "golang.org/x/sys/windows" - "golang.org/x/sys/windows/registry" - - "golang.zx2c4.com/wireguard/tun/wintun/iphlpapi" - "golang.zx2c4.com/wireguard/tun/wintun/nci" - registryEx "golang.zx2c4.com/wireguard/tun/wintun/registry" - "golang.zx2c4.com/wireguard/tun/wintun/setupapi" -) - -type Pool string - -type Interface struct { - cfgInstanceID windows.GUID - devInstanceID string - luidIndex uint32 - ifType uint32 - pool Pool -} - -var deviceClassNetGUID = windows.GUID{Data1: 0x4d36e972, Data2: 0xe325, Data3: 0x11ce, Data4: [8]byte{0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}} -var deviceInterfaceNetGUID = windows.GUID{Data1: 0xcac88484, Data2: 0x7515, Data3: 0x4c03, Data4: [8]byte{0x82, 0xe6, 0x71, 0xa8, 0x7a, 0xba, 0xc3, 0x61}} - -const ( - hardwareID = "Wintun" - waitForRegistryTimeout = time.Second * 10 -) - -// makeWintun creates a Wintun interface handle and populates it from the device's registry key. -func makeWintun(devInfo setupapi.DevInfo, devInfoData *setupapi.DevInfoData, pool Pool) (*Interface, error) { - // Open HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\\ registry key. - key, err := devInfo.OpenDevRegKey(devInfoData, setupapi.DICS_FLAG_GLOBAL, 0, setupapi.DIREG_DRV, registry.QUERY_VALUE) - if err != nil { - return nil, fmt.Errorf("Device-specific registry key open failed: %v", err) - } - defer key.Close() - - // Read the NetCfgInstanceId value. - valueStr, err := registryEx.GetStringValue(key, "NetCfgInstanceId") - if err != nil { - return nil, fmt.Errorf("RegQueryStringValue(\"NetCfgInstanceId\") failed: %v", err) - } - - // Convert to GUID. - ifid, err := windows.GUIDFromString(valueStr) - if err != nil { - return nil, fmt.Errorf("NetCfgInstanceId registry value is not a GUID (expected: \"{...}\", provided: %q)", valueStr) - } - - // Read the NetLuidIndex value. - luidIdx, _, err := key.GetIntegerValue("NetLuidIndex") - if err != nil { - return nil, fmt.Errorf("RegQueryValue(\"NetLuidIndex\") failed: %v", err) - } - - // Read the NetLuidIndex value. - ifType, _, err := key.GetIntegerValue("*IfType") - if err != nil { - return nil, fmt.Errorf("RegQueryValue(\"*IfType\") failed: %v", err) - } - - instanceID, err := devInfo.DeviceInstanceID(devInfoData) - if err != nil { - return nil, fmt.Errorf("DeviceInstanceID failed: %v", err) - } - - return &Interface{ - cfgInstanceID: ifid, - devInstanceID: instanceID, - luidIndex: uint32(luidIdx), - ifType: uint32(ifType), - pool: pool, - }, nil -} - -func removeNumberedSuffix(ifname string) string { - removed := strings.TrimRight(ifname, "0123456789") - if removed != ifname && len(removed) > 1 && removed[len(removed)-1] == ' ' { - return removed[:len(removed)-1] - } - return ifname -} - -// GetInterface finds a Wintun interface by its name. This function returns -// the interface if found, or windows.ERROR_OBJECT_NOT_FOUND otherwise. If -// the interface is found but not a Wintun-class or a member of the pool, -// this function returns windows.ERROR_ALREADY_EXISTS. -func (pool Pool) GetInterface(ifname string) (*Interface, error) { - mutex, err := pool.takeNameMutex() - if err != nil { - return nil, err - } - defer func() { - windows.ReleaseMutex(mutex) - windows.CloseHandle(mutex) - }() - - // Create a list of network devices. - devInfo, err := setupapi.SetupDiGetClassDevsEx(&deviceClassNetGUID, "", 0, setupapi.DIGCF_PRESENT, setupapi.DevInfo(0), "") - if err != nil { - return nil, fmt.Errorf("SetupDiGetClassDevsEx(%v) failed: %v", deviceClassNetGUID, err) - } - defer devInfo.Close() - - // Windows requires each interface to have a different name. When - // enforcing this, Windows treats interface names case-insensitive. If an - // interface "FooBar" exists and this function reports there is no - // interface "foobar", an attempt to create a new interface and name it - // "foobar" would cause conflict with "FooBar". - ifname = strings.ToLower(ifname) - - for index := 0; ; index++ { - devInfoData, err := devInfo.EnumDeviceInfo(index) - if err != nil { - if err == windows.ERROR_NO_MORE_ITEMS { - break - } - continue - } - - // Check the Hardware ID to make sure it's a real Wintun device first. This avoids doing slow operations on non-Wintun devices. - property, err := devInfo.DeviceRegistryProperty(devInfoData, setupapi.SPDRP_HARDWAREID) - if err != nil { - continue - } - if hwids, ok := property.([]string); ok && len(hwids) > 0 && hwids[0] != hardwareID { - continue - } - - wintun, err := makeWintun(devInfo, devInfoData, pool) - if err != nil { - continue - } - - // TODO: is there a better way than comparing ifnames? - ifname2, err := wintun.Name() - if err != nil { - continue - } - ifname2 = strings.ToLower(ifname2) - ifname3 := removeNumberedSuffix(ifname2) - - if ifname == ifname2 || ifname == ifname3 { - err = devInfo.BuildDriverInfoList(devInfoData, setupapi.SPDIT_COMPATDRIVER) - if err != nil { - return nil, fmt.Errorf("SetupDiBuildDriverInfoList failed: %v", err) - } - defer devInfo.DestroyDriverInfoList(devInfoData, setupapi.SPDIT_COMPATDRIVER) - - for index := 0; ; index++ { - driverData, err := devInfo.EnumDriverInfo(devInfoData, setupapi.SPDIT_COMPATDRIVER, index) - if err != nil { - if err == windows.ERROR_NO_MORE_ITEMS { - break - } - continue - } - - // Get driver info details. - driverDetailData, err := devInfo.DriverInfoDetail(devInfoData, driverData) - if err != nil { - continue - } - - if driverDetailData.IsCompatible(hardwareID) { - isMember, err := pool.isMember(devInfo, devInfoData) - if err != nil { - return nil, err - } - if !isMember { - return nil, windows.ERROR_ALREADY_EXISTS - } - - return wintun, nil - } - } - - // This interface is not using Wintun driver. - return nil, windows.ERROR_ALREADY_EXISTS - } - } - - return nil, windows.ERROR_OBJECT_NOT_FOUND -} - -// CreateInterface creates a Wintun interface. ifname is the requested name of -// the interface, while requestedGUID is the GUID of the created network -// interface, which then influences NLA generation deterministically. If it is -// set to nil, the GUID is chosen by the system at random, and hence a new NLA -// entry is created for each new interface. It is called "requested" GUID -// because the API it uses is completely undocumented, and so there could be minor -// interesting complications with its usage. This function returns the network -// interface ID and a flag if reboot is required. -func (pool Pool) CreateInterface(ifname string, requestedGUID *windows.GUID) (wintun *Interface, rebootRequired bool, err error) { - mutex, err := pool.takeNameMutex() - if err != nil { - return - } - defer func() { - windows.ReleaseMutex(mutex) - windows.CloseHandle(mutex) - }() - - // Create an empty device info set for network adapter device class. - devInfo, err := setupapi.SetupDiCreateDeviceInfoListEx(&deviceClassNetGUID, 0, "") - if err != nil { - err = fmt.Errorf("SetupDiCreateDeviceInfoListEx(%v) failed: %v", deviceClassNetGUID, err) - return - } - defer devInfo.Close() - - // Get the device class name from GUID. - className, err := setupapi.SetupDiClassNameFromGuidEx(&deviceClassNetGUID, "") - if err != nil { - err = fmt.Errorf("SetupDiClassNameFromGuidEx(%v) failed: %v", deviceClassNetGUID, err) - return - } - - // Create a new device info element and add it to the device info set. - deviceTypeName := pool.deviceTypeName() - devInfoData, err := devInfo.CreateDeviceInfo(className, &deviceClassNetGUID, deviceTypeName, 0, setupapi.DICD_GENERATE_ID) - if err != nil { - err = fmt.Errorf("SetupDiCreateDeviceInfo failed: %v", err) - return - } - - err = setQuietInstall(devInfo, devInfoData) - if err != nil { - err = fmt.Errorf("Setting quiet installation failed: %v", err) - return - } - - // Set a device information element as the selected member of a device information set. - err = devInfo.SetSelectedDevice(devInfoData) - if err != nil { - err = fmt.Errorf("SetupDiSetSelectedDevice failed: %v", err) - return - } - - // Set Plug&Play device hardware ID property. - err = devInfo.SetDeviceRegistryPropertyString(devInfoData, setupapi.SPDRP_HARDWAREID, hardwareID) - if err != nil { - err = fmt.Errorf("SetupDiSetDeviceRegistryProperty(SPDRP_HARDWAREID) failed: %v", err) - return - } - - err = devInfo.BuildDriverInfoList(devInfoData, setupapi.SPDIT_COMPATDRIVER) // TODO: This takes ~510ms - if err != nil { - err = fmt.Errorf("SetupDiBuildDriverInfoList failed: %v", err) - return - } - defer devInfo.DestroyDriverInfoList(devInfoData, setupapi.SPDIT_COMPATDRIVER) - - driverDate := windows.Filetime{} - driverVersion := uint64(0) - for index := 0; ; index++ { // TODO: This loop takes ~600ms - driverData, err := devInfo.EnumDriverInfo(devInfoData, setupapi.SPDIT_COMPATDRIVER, index) - if err != nil { - if err == windows.ERROR_NO_MORE_ITEMS { - break - } - continue - } - - // Check the driver version first, since the check is trivial and will save us iterating over hardware IDs for any driver versioned prior our best match. - if driverData.IsNewer(driverDate, driverVersion) { - driverDetailData, err := devInfo.DriverInfoDetail(devInfoData, driverData) - if err != nil { - continue - } - - if driverDetailData.IsCompatible(hardwareID) { - err := devInfo.SetSelectedDriver(devInfoData, driverData) - if err != nil { - continue - } - - driverDate = driverData.DriverDate - driverVersion = driverData.DriverVersion - } - } - } - - if driverVersion == 0 { - err = fmt.Errorf("No driver for device %q installed", hardwareID) - return - } - - defer func() { - if err != nil { - // The interface failed to install, or the interface ID was unobtainable. Clean-up. - removeDeviceParams := setupapi.RemoveDeviceParams{ - ClassInstallHeader: *setupapi.MakeClassInstallHeader(setupapi.DIF_REMOVE), - Scope: setupapi.DI_REMOVEDEVICE_GLOBAL, - } - - // Set class installer parameters for DIF_REMOVE. - if devInfo.SetClassInstallParams(devInfoData, &removeDeviceParams.ClassInstallHeader, uint32(unsafe.Sizeof(removeDeviceParams))) == nil { - // Call appropriate class installer. - if devInfo.CallClassInstaller(setupapi.DIF_REMOVE, devInfoData) == nil { - rebootRequired = rebootRequired || checkReboot(devInfo, devInfoData) - } - } - - wintun = nil - } - }() - - // Call appropriate class installer. - err = devInfo.CallClassInstaller(setupapi.DIF_REGISTERDEVICE, devInfoData) - if err != nil { - err = fmt.Errorf("SetupDiCallClassInstaller(DIF_REGISTERDEVICE) failed: %v", err) - return - } - - // Register device co-installers if any. (Ignore errors) - devInfo.CallClassInstaller(setupapi.DIF_REGISTER_COINSTALLERS, devInfoData) - - var netDevRegKey registry.Key - const pollTimeout = time.Millisecond * 50 - for i := 0; i < int(waitForRegistryTimeout/pollTimeout); i++ { - if i != 0 { - time.Sleep(pollTimeout) - } - netDevRegKey, err = devInfo.OpenDevRegKey(devInfoData, setupapi.DICS_FLAG_GLOBAL, 0, setupapi.DIREG_DRV, registry.SET_VALUE|registry.QUERY_VALUE|registry.NOTIFY) - if err == nil { - break - } - } - if err != nil { - err = fmt.Errorf("SetupDiOpenDevRegKey failed: %v", err) - return - } - defer netDevRegKey.Close() - if requestedGUID != nil { - err = netDevRegKey.SetStringValue("NetSetupAnticipatedInstanceId", requestedGUID.String()) - if err != nil { - err = fmt.Errorf("SetStringValue(NetSetupAnticipatedInstanceId) failed: %v", err) - return - } - } - - // Install interfaces if any. (Ignore errors) - devInfo.CallClassInstaller(setupapi.DIF_INSTALLINTERFACES, devInfoData) - - // Install the device. - err = devInfo.CallClassInstaller(setupapi.DIF_INSTALLDEVICE, devInfoData) - if err != nil { - err = fmt.Errorf("SetupDiCallClassInstaller(DIF_INSTALLDEVICE) failed: %v", err) - return - } - rebootRequired = checkReboot(devInfo, devInfoData) - - err = devInfo.SetDeviceRegistryPropertyString(devInfoData, setupapi.SPDRP_DEVICEDESC, deviceTypeName) - if err != nil { - err = fmt.Errorf("SetDeviceRegistryPropertyString(SPDRP_DEVICEDESC) failed: %v", err) - return - } - - // DIF_INSTALLDEVICE returns almost immediately, while the device installation - // continues in the background. It might take a while, before all registry - // keys and values are populated. - _, err = registryEx.GetStringValueWait(netDevRegKey, "NetCfgInstanceId", waitForRegistryTimeout) - if err != nil { - err = fmt.Errorf("GetStringValueWait(NetCfgInstanceId) failed: %v", err) - return - } - _, err = registryEx.GetIntegerValueWait(netDevRegKey, "NetLuidIndex", waitForRegistryTimeout) - if err != nil { - err = fmt.Errorf("GetIntegerValueWait(NetLuidIndex) failed: %v", err) - return - } - _, err = registryEx.GetIntegerValueWait(netDevRegKey, "*IfType", waitForRegistryTimeout) - if err != nil { - err = fmt.Errorf("GetIntegerValueWait(*IfType) failed: %v", err) - return - } - - // Get network interface. - wintun, err = makeWintun(devInfo, devInfoData, pool) - if err != nil { - err = fmt.Errorf("makeWintun failed: %v", err) - return - } - - // Wait for TCP/IP adapter registry key to emerge and populate. - tcpipAdapterRegKey, err := registryEx.OpenKeyWait( - registry.LOCAL_MACHINE, - wintun.tcpipAdapterRegKeyName(), registry.QUERY_VALUE|registry.NOTIFY, - waitForRegistryTimeout) - if err != nil { - err = fmt.Errorf("OpenKeyWait(HKLM\\%s) failed: %v", wintun.tcpipAdapterRegKeyName(), err) - return - } - defer tcpipAdapterRegKey.Close() - _, err = registryEx.GetStringValueWait(tcpipAdapterRegKey, "IpConfig", waitForRegistryTimeout) - if err != nil { - err = fmt.Errorf("GetStringValueWait(IpConfig) failed: %v", err) - return - } - - tcpipInterfaceRegKeyName, err := wintun.tcpipInterfaceRegKeyName() - if err != nil { - err = fmt.Errorf("tcpipInterfaceRegKeyName failed: %v", err) - return - } - - // Wait for TCP/IP interface registry key to emerge. - tcpipInterfaceRegKey, err := registryEx.OpenKeyWait( - registry.LOCAL_MACHINE, - tcpipInterfaceRegKeyName, registry.QUERY_VALUE|registry.SET_VALUE, - waitForRegistryTimeout) - if err != nil { - err = fmt.Errorf("OpenKeyWait(HKLM\\%s) failed: %v", tcpipInterfaceRegKeyName, err) - return - } - defer tcpipInterfaceRegKey.Close() - // Disable dead gateway detection on our interface. - tcpipInterfaceRegKey.SetDWordValue("EnableDeadGWDetect", 0) - - err = wintun.SetName(ifname) - if err != nil { - err = fmt.Errorf("Unable to set name of Wintun interface: %v", err) - return - } - - return -} - -// DeleteInterface deletes a Wintun interface. This function succeeds -// if the interface was not found. It returns a bool indicating whether -// a reboot is required. -func (wintun *Interface) DeleteInterface() (rebootRequired bool, err error) { - devInfo, devInfoData, err := wintun.devInfoData() - if err == windows.ERROR_OBJECT_NOT_FOUND { - return false, nil - } - if err != nil { - return false, err - } - defer devInfo.Close() - - // Remove the device. - removeDeviceParams := setupapi.RemoveDeviceParams{ - ClassInstallHeader: *setupapi.MakeClassInstallHeader(setupapi.DIF_REMOVE), - Scope: setupapi.DI_REMOVEDEVICE_GLOBAL, - } - - // Set class installer parameters for DIF_REMOVE. - err = devInfo.SetClassInstallParams(devInfoData, &removeDeviceParams.ClassInstallHeader, uint32(unsafe.Sizeof(removeDeviceParams))) - if err != nil { - return false, fmt.Errorf("SetupDiSetClassInstallParams failed: %v", err) - } - - // Call appropriate class installer. - err = devInfo.CallClassInstaller(setupapi.DIF_REMOVE, devInfoData) - if err != nil { - return false, fmt.Errorf("SetupDiCallClassInstaller failed: %v", err) - } - - return checkReboot(devInfo, devInfoData), nil -} - -// DeleteMatchingInterfaces deletes all Wintun interfaces, which match -// given criteria, and returns which ones it deleted, whether a reboot -// is required after, and which errors occurred during the process. -func (pool Pool) DeleteMatchingInterfaces(matches func(wintun *Interface) bool) (deviceInstancesDeleted []uint32, rebootRequired bool, errors []error) { - mutex, err := pool.takeNameMutex() - if err != nil { - errors = append(errors, err) - return - } - defer func() { - windows.ReleaseMutex(mutex) - windows.CloseHandle(mutex) - }() - - devInfo, err := setupapi.SetupDiGetClassDevsEx(&deviceClassNetGUID, "", 0, setupapi.DIGCF_PRESENT, setupapi.DevInfo(0), "") - if err != nil { - return nil, false, []error{fmt.Errorf("SetupDiGetClassDevsEx(%v) failed: %v", deviceClassNetGUID, err.Error())} - } - defer devInfo.Close() - - for i := 0; ; i++ { - devInfoData, err := devInfo.EnumDeviceInfo(i) - if err != nil { - if err == windows.ERROR_NO_MORE_ITEMS { - break - } - continue - } - - // Check the Hardware ID to make sure it's a real Wintun device first. This avoids doing slow operations on non-Wintun devices. - property, err := devInfo.DeviceRegistryProperty(devInfoData, setupapi.SPDRP_HARDWAREID) - if err != nil { - continue - } - if hwids, ok := property.([]string); ok && len(hwids) > 0 && hwids[0] != hardwareID { - continue - } - - err = devInfo.BuildDriverInfoList(devInfoData, setupapi.SPDIT_COMPATDRIVER) - if err != nil { - continue - } - defer devInfo.DestroyDriverInfoList(devInfoData, setupapi.SPDIT_COMPATDRIVER) - - isWintun := false - for j := 0; ; j++ { - driverData, err := devInfo.EnumDriverInfo(devInfoData, setupapi.SPDIT_COMPATDRIVER, j) - if err != nil { - if err == windows.ERROR_NO_MORE_ITEMS { - break - } - continue - } - driverDetailData, err := devInfo.DriverInfoDetail(devInfoData, driverData) - if err != nil { - continue - } - if driverDetailData.IsCompatible(hardwareID) { - isWintun = true - break - } - } - if !isWintun { - continue - } - - isMember, err := pool.isMember(devInfo, devInfoData) - if err != nil { - errors = append(errors, err) - continue - } - if !isMember { - continue - } - - wintun, err := makeWintun(devInfo, devInfoData, pool) - if err != nil { - errors = append(errors, fmt.Errorf("Unable to make Wintun interface object: %v", err)) - continue - } - if !matches(wintun) { - continue - } - - err = setQuietInstall(devInfo, devInfoData) - if err != nil { - errors = append(errors, err) - continue - } - - inst := devInfoData.DevInst - removeDeviceParams := setupapi.RemoveDeviceParams{ - ClassInstallHeader: *setupapi.MakeClassInstallHeader(setupapi.DIF_REMOVE), - Scope: setupapi.DI_REMOVEDEVICE_GLOBAL, - } - err = devInfo.SetClassInstallParams(devInfoData, &removeDeviceParams.ClassInstallHeader, uint32(unsafe.Sizeof(removeDeviceParams))) - if err != nil { - errors = append(errors, err) - continue - } - err = devInfo.CallClassInstaller(setupapi.DIF_REMOVE, devInfoData) - if err != nil { - errors = append(errors, err) - continue - } - rebootRequired = rebootRequired || checkReboot(devInfo, devInfoData) - deviceInstancesDeleted = append(deviceInstancesDeleted, inst) - } - return -} - -// isMember checks if SPDRP_DEVICEDESC or SPDRP_FRIENDLYNAME match device type name. -func (pool Pool) isMember(devInfo setupapi.DevInfo, devInfoData *setupapi.DevInfoData) (bool, error) { - deviceDescVal, err := devInfo.DeviceRegistryProperty(devInfoData, setupapi.SPDRP_DEVICEDESC) - if err != nil { - return false, fmt.Errorf("DeviceRegistryPropertyString(SPDRP_DEVICEDESC) failed: %v", err) - } - deviceDesc, _ := deviceDescVal.(string) - friendlyNameVal, err := devInfo.DeviceRegistryProperty(devInfoData, setupapi.SPDRP_FRIENDLYNAME) - if err != nil { - return false, fmt.Errorf("DeviceRegistryPropertyString(SPDRP_FRIENDLYNAME) failed: %v", err) - } - friendlyName, _ := friendlyNameVal.(string) - deviceTypeName := pool.deviceTypeName() - return friendlyName == deviceTypeName || deviceDesc == deviceTypeName || - removeNumberedSuffix(friendlyName) == deviceTypeName || removeNumberedSuffix(deviceDesc) == deviceTypeName, nil -} - -// checkReboot checks device install parameters if a system reboot is required. -func checkReboot(devInfo setupapi.DevInfo, devInfoData *setupapi.DevInfoData) bool { - devInstallParams, err := devInfo.DeviceInstallParams(devInfoData) - if err != nil { - return false - } - - return (devInstallParams.Flags & (setupapi.DI_NEEDREBOOT | setupapi.DI_NEEDRESTART)) != 0 -} - -// setQuietInstall sets device install parameters for a quiet installation -func setQuietInstall(devInfo setupapi.DevInfo, devInfoData *setupapi.DevInfoData) error { - devInstallParams, err := devInfo.DeviceInstallParams(devInfoData) - if err != nil { - return err - } - - devInstallParams.Flags |= setupapi.DI_QUIETINSTALL - return devInfo.SetDeviceInstallParams(devInfoData, devInstallParams) -} - -// deviceTypeName returns pool-specific device type name. -func (pool Pool) deviceTypeName() string { - return fmt.Sprintf("%s Tunnel", pool) -} - -// Name returns the name of the Wintun interface. -func (wintun *Interface) Name() (string, error) { - return nci.ConnectionName(&wintun.cfgInstanceID) -} - -// SetName sets name of the Wintun interface. -func (wintun *Interface) SetName(ifname string) error { - const maxSuffix = 1000 - availableIfname := ifname - for i := 0; ; i++ { - err := nci.SetConnectionName(&wintun.cfgInstanceID, availableIfname) - if err == windows.ERROR_DUP_NAME { - duplicateGuid, err2 := iphlpapi.InterfaceGUIDFromAlias(availableIfname) - if err2 == nil { - for j := 0; j < maxSuffix; j++ { - proposal := fmt.Sprintf("%s %d", ifname, j+1) - if proposal == availableIfname { - continue - } - err2 = nci.SetConnectionName(duplicateGuid, proposal) - if err2 == windows.ERROR_DUP_NAME { - continue - } - if err2 == nil { - err = nci.SetConnectionName(&wintun.cfgInstanceID, availableIfname) - if err == nil { - break - } - } - break - } - } - } - if err == nil { - break - } - - if i > maxSuffix || err != windows.ERROR_DUP_NAME { - return fmt.Errorf("NciSetConnectionName failed: %v", err) - } - availableIfname = fmt.Sprintf("%s %d", ifname, i+1) - } - - // TODO: This should use NetSetup2 so that it doesn't get unset. - deviceRegKey, err := registry.OpenKey(registry.LOCAL_MACHINE, wintun.deviceRegKeyName(), registry.SET_VALUE) - if err != nil { - return fmt.Errorf("Device-level registry key open failed: %v", err) - } - defer deviceRegKey.Close() - err = deviceRegKey.SetStringValue("FriendlyName", wintun.pool.deviceTypeName()) - if err != nil { - return fmt.Errorf("SetStringValue(FriendlyName) failed: %v", err) - } - return nil -} - -// tcpipAdapterRegKeyName returns the adapter-specific TCP/IP network registry key name. -func (wintun *Interface) tcpipAdapterRegKeyName() string { - return fmt.Sprintf("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters\\%v", wintun.cfgInstanceID) -} - -// deviceRegKeyName returns the device-level registry key name. -func (wintun *Interface) deviceRegKeyName() string { - return fmt.Sprintf("SYSTEM\\CurrentControlSet\\Enum\\%v", wintun.devInstanceID) -} - -// Version returns the version of the Wintun driver and NDIS system currently loaded. -func (wintun *Interface) Version() (driverVersion string, ndisVersion string, err error) { - key, err := registry.OpenKey(registry.LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Wintun", registry.QUERY_VALUE) - if err != nil { - return - } - defer key.Close() - driverMajor, _, err := key.GetIntegerValue("DriverMajorVersion") - if err != nil { - return - } - driverMinor, _, err := key.GetIntegerValue("DriverMinorVersion") - if err != nil { - return - } - ndisMajor, _, err := key.GetIntegerValue("NdisMajorVersion") - if err != nil { - return - } - ndisMinor, _, err := key.GetIntegerValue("NdisMinorVersion") - if err != nil { - return - } - driverVersion = fmt.Sprintf("%d.%d", driverMajor, driverMinor) - ndisVersion = fmt.Sprintf("%d.%d", ndisMajor, ndisMinor) - return -} - -// tcpipInterfaceRegKeyName returns the interface-specific TCP/IP network registry key name. -func (wintun *Interface) tcpipInterfaceRegKeyName() (path string, err error) { - key, err := registry.OpenKey(registry.LOCAL_MACHINE, wintun.tcpipAdapterRegKeyName(), registry.QUERY_VALUE) - if err != nil { - return "", fmt.Errorf("Error opening adapter-specific TCP/IP network registry key: %v", err) - } - paths, _, err := key.GetStringsValue("IpConfig") - key.Close() - if err != nil { - return "", fmt.Errorf("Error reading IpConfig registry key: %v", err) - } - if len(paths) == 0 { - return "", errors.New("No TCP/IP interfaces found on adapter") - } - return fmt.Sprintf("SYSTEM\\CurrentControlSet\\Services\\%s", paths[0]), nil -} - -// devInfoData returns TUN device info list handle and interface device info -// data. The device info list handle must be closed after use. In case the -// device is not found, windows.ERROR_OBJECT_NOT_FOUND is returned. -func (wintun *Interface) devInfoData() (setupapi.DevInfo, *setupapi.DevInfoData, error) { - // Create a list of network devices. - devInfo, err := setupapi.SetupDiGetClassDevsEx(&deviceClassNetGUID, "", 0, setupapi.DIGCF_PRESENT, setupapi.DevInfo(0), "") - if err != nil { - return 0, nil, fmt.Errorf("SetupDiGetClassDevsEx(%v) failed: %v", deviceClassNetGUID, err.Error()) - } - - for index := 0; ; index++ { - devInfoData, err := devInfo.EnumDeviceInfo(index) - if err != nil { - if err == windows.ERROR_NO_MORE_ITEMS { - break - } - continue - } - - // Get interface ID. - // TODO: Store some ID in the Wintun object such that this call isn't required. - wintun2, err := makeWintun(devInfo, devInfoData, wintun.pool) - if err != nil { - continue - } - - if wintun.cfgInstanceID == wintun2.cfgInstanceID { - err = setQuietInstall(devInfo, devInfoData) - if err != nil { - devInfo.Close() - return 0, nil, fmt.Errorf("Setting quiet installation failed: %v", err) - } - return devInfo, devInfoData, nil - } - } - - devInfo.Close() - return 0, nil, windows.ERROR_OBJECT_NOT_FOUND -} - -// handle returns a handle to the interface device object. -func (wintun *Interface) handle() (windows.Handle, error) { - interfaces, err := setupapi.CM_Get_Device_Interface_List(wintun.devInstanceID, &deviceInterfaceNetGUID, setupapi.CM_GET_DEVICE_INTERFACE_LIST_PRESENT) - if err != nil { - return windows.InvalidHandle, fmt.Errorf("Error listing NDIS interfaces: %v", err) - } - handle, err := windows.CreateFile(windows.StringToUTF16Ptr(interfaces[0]), windows.GENERIC_READ|windows.GENERIC_WRITE, windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE|windows.FILE_SHARE_DELETE, nil, windows.OPEN_EXISTING, 0, 0) - if err != nil { - return windows.InvalidHandle, fmt.Errorf("Error opening NDIS device: %v", err) - } - return handle, nil -} - -// GUID returns the GUID of the interface. -func (wintun *Interface) GUID() windows.GUID { - return wintun.cfgInstanceID -} - -// LUID returns the LUID of the interface. -func (wintun *Interface) LUID() uint64 { - return ((uint64(wintun.luidIndex) & ((1 << 24) - 1)) << 24) | ((uint64(wintun.ifType) & ((1 << 16) - 1)) << 48) -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 6ba716e072..a12a641373 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -489,7 +489,7 @@ github.com/skycoin/skycoin-service-discovery/internal/pg github.com/skycoin/skycoin-service-discovery/internal/sdmetrics github.com/skycoin/skycoin-service-discovery/pkg/service-discovery/api github.com/skycoin/skycoin-service-discovery/pkg/service-discovery/store -# github.com/skycoin/skywire-services v0.0.0-20231221001820-3212895ddf12 +# github.com/skycoin/skywire-services v0.0.0-20240207001624-ebee7346e526 ## explicit; go 1.21 github.com/skycoin/skywire-services/cmd/address-resolver/commands github.com/skycoin/skywire-services/cmd/config-bootstrapper/commands @@ -737,16 +737,13 @@ golang.org/x/tools/internal/pkgbits golang.org/x/tools/internal/tokeninternal golang.org/x/tools/internal/typeparams golang.org/x/tools/internal/typesinternal -# golang.zx2c4.com/wireguard v0.0.20200320 -## explicit; go 1.12 +# golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 +## explicit; go 1.17 +golang.zx2c4.com/wintun +# golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675 +## explicit; go 1.19 golang.zx2c4.com/wireguard/rwcancel golang.zx2c4.com/wireguard/tun -golang.zx2c4.com/wireguard/tun/wintun -golang.zx2c4.com/wireguard/tun/wintun/iphlpapi -golang.zx2c4.com/wireguard/tun/wintun/namespaceapi -golang.zx2c4.com/wireguard/tun/wintun/nci -golang.zx2c4.com/wireguard/tun/wintun/registry -golang.zx2c4.com/wireguard/tun/wintun/setupapi # google.golang.org/protobuf v1.31.0 ## explicit; go 1.11 google.golang.org/protobuf/encoding/prototext