wgctrl-go/internal/wguser/client.go
Matt Layher 73a2818380
internal/wguser: preallocate devices slice capacity
Signed-off-by: Matt Layher <mdlayher@gmail.com>
2021-12-08 17:56:14 -05:00

100 lines
2.0 KiB
Go

package wguser
import (
"fmt"
"net"
"os"
"path/filepath"
"strings"
"golang.zx2c4.com/wireguard/wgctrl/internal/wginternal"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
var _ wginternal.Client = &Client{}
// A Client provides access to userspace WireGuard device information.
type Client struct {
dial func(device string) (net.Conn, error)
find func() ([]string, error)
}
// New creates a new Client.
func New() (*Client, error) {
return &Client{
// Operating system-specific functions which can identify and connect
// to userspace WireGuard devices. These functions can also be
// overridden for tests.
dial: dial,
find: find,
}, nil
}
// Close implements wginternal.Client.
func (c *Client) Close() error { return nil }
// Devices implements wginternal.Client.
func (c *Client) Devices() ([]*wgtypes.Device, error) {
devices, err := c.find()
if err != nil {
return nil, err
}
wgds := make([]*wgtypes.Device, 0, len(devices))
for _, d := range devices {
wgd, err := c.getDevice(d)
if err != nil {
return nil, err
}
wgds = append(wgds, wgd)
}
return wgds, nil
}
// Device implements wginternal.Client.
func (c *Client) Device(name string) (*wgtypes.Device, error) {
devices, err := c.find()
if err != nil {
return nil, err
}
for _, d := range devices {
if name != deviceName(d) {
continue
}
return c.getDevice(d)
}
return nil, os.ErrNotExist
}
// ConfigureDevice implements wginternal.Client.
func (c *Client) ConfigureDevice(name string, cfg wgtypes.Config) error {
devices, err := c.find()
if err != nil {
return err
}
for _, d := range devices {
if name != deviceName(d) {
continue
}
return c.configureDevice(d, cfg)
}
return os.ErrNotExist
}
// deviceName infers a device name from an absolute file path with extension.
func deviceName(sock string) string {
return strings.TrimSuffix(filepath.Base(sock), filepath.Ext(sock))
}
func panicf(format string, a ...interface{}) {
panic(fmt.Sprintf(format, a...))
}