mirror of
https://github.com/netbirdio/netbird.git
synced 2025-06-19 00:06:58 +02:00
refactor: rearrange iface package
This commit is contained in:
parent
f2ca2fc7c1
commit
a40669270a
256
iface/iface.go
256
iface/iface.go
@ -1,9 +1,253 @@
|
|||||||
// +build !linux
|
|
||||||
|
|
||||||
package iface
|
package iface
|
||||||
|
|
||||||
// Create Creates a new Wireguard interface, sets a given IP and brings it up.
|
import (
|
||||||
// Will reuse an existing one.
|
log "github.com/sirupsen/logrus"
|
||||||
func Create(iface string, address string) error {
|
"golang.zx2c4.com/wireguard/conn"
|
||||||
return CreateWithUserspace(iface, address)
|
"golang.zx2c4.com/wireguard/device"
|
||||||
|
"golang.zx2c4.com/wireguard/tun"
|
||||||
|
"golang.zx2c4.com/wireguard/wgctrl"
|
||||||
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultMTU = 1280
|
||||||
|
WgPort = 51820
|
||||||
|
)
|
||||||
|
|
||||||
|
var tunIface tun.Device
|
||||||
|
|
||||||
|
// CreateWithUserspace Creates a new Wireguard interface, using wireguard-go userspace implementation
|
||||||
|
func CreateWithUserspace(iface string, address string) error {
|
||||||
|
var err error
|
||||||
|
tunIface, err = tun.CreateTUN(iface, defaultMTU)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to create a wireguard-go device and listen to configuration requests
|
||||||
|
tunDevice := device.NewDevice(tunIface, conn.NewDefaultBind(), device.NewLogger(device.LogLevelSilent, "[wiretrustee] "))
|
||||||
|
err = tunDevice.Up()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
uapi, err := getUAPI(iface)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
uapiConn, err := uapi.Accept()
|
||||||
|
if err != nil {
|
||||||
|
log.Debugln(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go tunDevice.IpcHandle(uapiConn)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
log.Debugln("UAPI listener started")
|
||||||
|
|
||||||
|
err = assignAddr(address, iface)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigureWithKeyGen Extends the functionality of Configure(iface string, privateKey string) by generating a new Wireguard private key
|
||||||
|
func ConfigureWithKeyGen(iface string) (*wgtypes.Key, error) {
|
||||||
|
key, err := wgtypes.GeneratePrivateKey()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &key, Configure(iface, key.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure configures a Wireguard interface
|
||||||
|
// The interface must exist before calling this method (e.g. call interface.Create() before)
|
||||||
|
func Configure(iface string, privateKey string) error {
|
||||||
|
|
||||||
|
log.Debugf("configuring Wireguard interface %s", iface)
|
||||||
|
wg, err := wgctrl.New()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer wg.Close()
|
||||||
|
|
||||||
|
log.Debugf("adding Wireguard private key")
|
||||||
|
key, err := wgtypes.ParseKey(privateKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fwmark := 0
|
||||||
|
p := WgPort
|
||||||
|
cfg := wgtypes.Config{
|
||||||
|
PrivateKey: &key,
|
||||||
|
ReplacePeers: false,
|
||||||
|
FirewallMark: &fwmark,
|
||||||
|
ListenPort: &p,
|
||||||
|
}
|
||||||
|
err = wg.ConfigureDevice(iface, cfg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetListenPort returns the listening port of the Wireguard endpoint
|
||||||
|
func GetListenPort(iface string) (*int, error) {
|
||||||
|
log.Debugf("getting Wireguard listen port of interface %s", iface)
|
||||||
|
|
||||||
|
//discover Wireguard current configuration
|
||||||
|
wg, err := wgctrl.New()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer wg.Close()
|
||||||
|
|
||||||
|
d, err := wg.Device(iface)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
log.Debugf("got Wireguard device listen port %s, %d", iface, &d.ListenPort)
|
||||||
|
|
||||||
|
return &d.ListenPort, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateListenPort updates a Wireguard interface listen port
|
||||||
|
func UpdateListenPort(iface string, newPort int) error {
|
||||||
|
log.Debugf("updating Wireguard listen port of interface %s, new port %d", iface, newPort)
|
||||||
|
|
||||||
|
//discover Wireguard current configuration
|
||||||
|
wg, err := wgctrl.New()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer wg.Close()
|
||||||
|
|
||||||
|
_, err = wg.Device(iface)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Debugf("got Wireguard device %s", iface)
|
||||||
|
|
||||||
|
config := wgtypes.Config{
|
||||||
|
ListenPort: &newPort,
|
||||||
|
ReplacePeers: false,
|
||||||
|
}
|
||||||
|
err = wg.ConfigureDevice(iface, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("updated Wireguard listen port of interface %s, new port %d", iface, newPort)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatePeer updates existing Wireguard Peer or creates a new one if doesn't exist
|
||||||
|
// Endpoint is optional
|
||||||
|
func UpdatePeer(iface string, peerKey string, allowedIps string, keepAlive time.Duration, endpoint string) error {
|
||||||
|
|
||||||
|
log.Debugf("updating interface %s peer %s: endpoint %s ", iface, peerKey, endpoint)
|
||||||
|
|
||||||
|
wg, err := wgctrl.New()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer wg.Close()
|
||||||
|
|
||||||
|
_, err = wg.Device(iface)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Debugf("got Wireguard device %s", iface)
|
||||||
|
|
||||||
|
//parse allowed ips
|
||||||
|
_, ipNet, err := net.ParseCIDR(allowedIps)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
peerKeyParsed, err := wgtypes.ParseKey(peerKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
peers := make([]wgtypes.PeerConfig, 0)
|
||||||
|
peer := wgtypes.PeerConfig{
|
||||||
|
PublicKey: peerKeyParsed,
|
||||||
|
ReplaceAllowedIPs: true,
|
||||||
|
AllowedIPs: []net.IPNet{*ipNet},
|
||||||
|
PersistentKeepaliveInterval: &keepAlive,
|
||||||
|
}
|
||||||
|
peers = append(peers, peer)
|
||||||
|
|
||||||
|
config := wgtypes.Config{
|
||||||
|
ReplacePeers: false,
|
||||||
|
Peers: peers,
|
||||||
|
}
|
||||||
|
err = wg.ConfigureDevice(iface, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if endpoint != "" {
|
||||||
|
return UpdatePeerEndpoint(iface, peerKey, endpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatePeerEndpoint updates a Wireguard interface Peer with the new endpoint
|
||||||
|
// Used when NAT hole punching was successful and an update of the remote peer endpoint is required
|
||||||
|
func UpdatePeerEndpoint(iface string, peerKey string, newEndpoint string) error {
|
||||||
|
|
||||||
|
log.Debugf("updating peer %s endpoint %s ", peerKey, newEndpoint)
|
||||||
|
|
||||||
|
wg, err := wgctrl.New()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer wg.Close()
|
||||||
|
|
||||||
|
_, err = wg.Device(iface)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Debugf("got Wireguard device %s", iface)
|
||||||
|
|
||||||
|
peerAddr, err := net.ResolveUDPAddr("udp4", newEndpoint)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("parsed peer endpoint [%s]", peerAddr.String())
|
||||||
|
|
||||||
|
peerKeyParsed, err := wgtypes.ParseKey(peerKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
peers := make([]wgtypes.PeerConfig, 0)
|
||||||
|
peer := wgtypes.PeerConfig{
|
||||||
|
PublicKey: peerKeyParsed,
|
||||||
|
ReplaceAllowedIPs: false,
|
||||||
|
UpdateOnly: true,
|
||||||
|
Endpoint: peerAddr,
|
||||||
|
}
|
||||||
|
peers = append(peers, peer)
|
||||||
|
|
||||||
|
config := wgtypes.Config{
|
||||||
|
ReplacePeers: false,
|
||||||
|
Peers: peers,
|
||||||
|
}
|
||||||
|
err = wg.ConfigureDevice(iface, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,256 +0,0 @@
|
|||||||
package iface
|
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.zx2c4.com/wireguard/conn"
|
|
||||||
"golang.zx2c4.com/wireguard/device"
|
|
||||||
"golang.zx2c4.com/wireguard/tun"
|
|
||||||
"net"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"golang.zx2c4.com/wireguard/wgctrl"
|
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
defaultMTU = 1280
|
|
||||||
WgPort = 51820
|
|
||||||
)
|
|
||||||
|
|
||||||
// ConfigureWithKeyGen Extends the functionality of Configure(iface string, privateKey string) by generating a new Wireguard private key
|
|
||||||
func ConfigureWithKeyGen(iface string) (*wgtypes.Key, error) {
|
|
||||||
key, err := wgtypes.GeneratePrivateKey()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &key, Configure(iface, key.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateWithUserspace Creates a new Wireguard interface, using wireguard-go userspace implementation
|
|
||||||
func CreateWithUserspace(iface string, address string) error {
|
|
||||||
var err error
|
|
||||||
tunIface, err := tun.CreateTUN(iface, defaultMTU)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need to create a wireguard-go device and listen to configuration requests
|
|
||||||
tunDevice := device.NewDevice(tunIface, conn.NewDefaultBind(), device.NewLogger(device.LogLevelSilent, "[wiretrustee] "))
|
|
||||||
err = tunDevice.Up()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
uapi, err := getUAPI(iface)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
uapiConn, err := uapi.Accept()
|
|
||||||
if err != nil {
|
|
||||||
log.Debugln(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
go tunDevice.IpcHandle(uapiConn)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
log.Debugln("UAPI listener started")
|
|
||||||
|
|
||||||
ifaceName, err := tunIface.Name()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = assignAddr(address, ifaceName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure configures a Wireguard interface
|
|
||||||
// The interface must exist before calling this method (e.g. call interface.Create() before)
|
|
||||||
func Configure(iface string, privateKey string) error {
|
|
||||||
|
|
||||||
log.Debugf("configuring Wireguard interface %s", iface)
|
|
||||||
wg, err := wgctrl.New()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer wg.Close()
|
|
||||||
|
|
||||||
log.Debugf("adding Wireguard private key")
|
|
||||||
key, err := wgtypes.ParseKey(privateKey)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fwmark := 0
|
|
||||||
p := WgPort
|
|
||||||
cfg := wgtypes.Config{
|
|
||||||
PrivateKey: &key,
|
|
||||||
ReplacePeers: false,
|
|
||||||
FirewallMark: &fwmark,
|
|
||||||
ListenPort: &p,
|
|
||||||
}
|
|
||||||
err = wg.ConfigureDevice(iface, cfg)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetListenPort returns the listening port of the Wireguard endpoint
|
|
||||||
func GetListenPort(iface string) (*int, error) {
|
|
||||||
log.Debugf("getting Wireguard listen port of interface %s", iface)
|
|
||||||
|
|
||||||
//discover Wireguard current configuration
|
|
||||||
wg, err := wgctrl.New()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer wg.Close()
|
|
||||||
|
|
||||||
d, err := wg.Device(iface)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
log.Debugf("got Wireguard device listen port %s, %d", iface, &d.ListenPort)
|
|
||||||
|
|
||||||
return &d.ListenPort, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateListenPort updates a Wireguard interface listen port
|
|
||||||
func UpdateListenPort(iface string, newPort int) error {
|
|
||||||
log.Debugf("updating Wireguard listen port of interface %s, new port %d", iface, newPort)
|
|
||||||
|
|
||||||
//discover Wireguard current configuration
|
|
||||||
wg, err := wgctrl.New()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer wg.Close()
|
|
||||||
|
|
||||||
_, err = wg.Device(iface)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Debugf("got Wireguard device %s", iface)
|
|
||||||
|
|
||||||
config := wgtypes.Config{
|
|
||||||
ListenPort: &newPort,
|
|
||||||
ReplacePeers: false,
|
|
||||||
}
|
|
||||||
err = wg.ConfigureDevice(iface, config)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("updated Wireguard listen port of interface %s, new port %d", iface, newPort)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdatePeer updates existing Wireguard Peer or creates a new one if doesn't exist
|
|
||||||
// Endpoint is optional
|
|
||||||
func UpdatePeer(iface string, peerKey string, allowedIps string, keepAlive time.Duration, endpoint string) error {
|
|
||||||
|
|
||||||
log.Debugf("updating interface %s peer %s: endpoint %s ", iface, peerKey, endpoint)
|
|
||||||
|
|
||||||
wg, err := wgctrl.New()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer wg.Close()
|
|
||||||
|
|
||||||
_, err = wg.Device(iface)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Debugf("got Wireguard device %s", iface)
|
|
||||||
|
|
||||||
//parse allowed ips
|
|
||||||
_, ipNet, err := net.ParseCIDR(allowedIps)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
peerKeyParsed, err := wgtypes.ParseKey(peerKey)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
peers := make([]wgtypes.PeerConfig, 0)
|
|
||||||
peer := wgtypes.PeerConfig{
|
|
||||||
PublicKey: peerKeyParsed,
|
|
||||||
ReplaceAllowedIPs: true,
|
|
||||||
AllowedIPs: []net.IPNet{*ipNet},
|
|
||||||
PersistentKeepaliveInterval: &keepAlive,
|
|
||||||
}
|
|
||||||
peers = append(peers, peer)
|
|
||||||
|
|
||||||
config := wgtypes.Config{
|
|
||||||
ReplacePeers: false,
|
|
||||||
Peers: peers,
|
|
||||||
}
|
|
||||||
err = wg.ConfigureDevice(iface, config)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if endpoint != "" {
|
|
||||||
return UpdatePeerEndpoint(iface, peerKey, endpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdatePeerEndpoint updates a Wireguard interface Peer with the new endpoint
|
|
||||||
// Used when NAT hole punching was successful and an update of the remote peer endpoint is required
|
|
||||||
func UpdatePeerEndpoint(iface string, peerKey string, newEndpoint string) error {
|
|
||||||
|
|
||||||
log.Debugf("updating peer %s endpoint %s ", peerKey, newEndpoint)
|
|
||||||
|
|
||||||
wg, err := wgctrl.New()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer wg.Close()
|
|
||||||
|
|
||||||
_, err = wg.Device(iface)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Debugf("got Wireguard device %s", iface)
|
|
||||||
|
|
||||||
peerAddr, err := net.ResolveUDPAddr("udp4", newEndpoint)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("parsed peer endpoint [%s]", peerAddr.String())
|
|
||||||
|
|
||||||
peerKeyParsed, err := wgtypes.ParseKey(peerKey)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
peers := make([]wgtypes.PeerConfig, 0)
|
|
||||||
peer := wgtypes.PeerConfig{
|
|
||||||
PublicKey: peerKeyParsed,
|
|
||||||
ReplaceAllowedIPs: false,
|
|
||||||
UpdateOnly: true,
|
|
||||||
Endpoint: peerAddr,
|
|
||||||
}
|
|
||||||
peers = append(peers, peer)
|
|
||||||
|
|
||||||
config := wgtypes.Config{
|
|
||||||
ReplacePeers: false,
|
|
||||||
Peers: peers,
|
|
||||||
}
|
|
||||||
err = wg.ConfigureDevice(iface, config)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -7,9 +7,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
//const (
|
// Create Creates a new Wireguard interface, sets a given IP and brings it up.
|
||||||
// interfacePrefix = "utun"
|
func Create(iface string, address string) error {
|
||||||
//)
|
return CreateWithUserspace(iface, address)
|
||||||
|
}
|
||||||
|
|
||||||
// assignAddr Adds IP address to the tunnel interface and network route based on the range provided
|
// assignAddr Adds IP address to the tunnel interface and network route based on the range provided
|
||||||
func assignAddr(address string, ifaceName string) error {
|
func assignAddr(address string, ifaceName string) error {
|
||||||
|
@ -15,7 +15,6 @@ func Create(iface string, address string) error {
|
|||||||
} else {
|
} else {
|
||||||
return CreateWithUserspace(iface, address)
|
return CreateWithUserspace(iface, address)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateWithKernel Creates a new Wireguard interface using kernel Wireguard module.
|
// CreateWithKernel Creates a new Wireguard interface using kernel Wireguard module.
|
||||||
|
@ -8,10 +8,15 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Create Creates a new Wireguard interface, sets a given IP and brings it up.
|
||||||
|
func Create(iface string, address string) error {
|
||||||
|
return CreateWithUserspace(iface, address)
|
||||||
|
}
|
||||||
|
|
||||||
// assignAddr Adds IP address to the tunnel interface and network route based on the range provided
|
// assignAddr Adds IP address to the tunnel interface and network route based on the range provided
|
||||||
func assignAddr(address string, ifaceName string) error {
|
func assignAddr(address string, ifaceName string) error {
|
||||||
|
|
||||||
nativeTunDevice := tunDevice.(*tun.NativeTun)
|
nativeTunDevice := tunIface.(*tun.NativeTun)
|
||||||
luid := winipcfg.LUID(nativeTunDevice.LUID())
|
luid := winipcfg.LUID(nativeTunDevice.LUID())
|
||||||
|
|
||||||
ip, ipnet, _ := net.ParseCIDR(address)
|
ip, ipnet, _ := net.ParseCIDR(address)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user