Skip to content

Commit

Permalink
Move wireguard cfg to a leaf package without deps
Browse files Browse the repository at this point in the history
So that supervisor can using without pulling all the bad stuff
  • Loading branch information
tadaskay committed Jun 2, 2020
1 parent 3a72819 commit 924532c
Show file tree
Hide file tree
Showing 25 changed files with 268 additions and 240 deletions.
9 changes: 5 additions & 4 deletions mobile/mysterium/wireguard_connection_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
wireguard_connection "github.com/mysteriumnetwork/node/services/wireguard/connection"
"github.com/mysteriumnetwork/node/services/wireguard/endpoint/userspace"
"github.com/mysteriumnetwork/node/services/wireguard/key"
"github.com/mysteriumnetwork/node/services/wireguard/wgcfg"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
"golang.zx2c4.com/wireguard/device"
Expand Down Expand Up @@ -178,7 +179,7 @@ func (c *wireguardConnection) GetConfig() (connection.ConsumerConfig, error) {
type wireguardDevice interface {
Start(privateKey string, config wireguard.ServiceConfig, channelConn *net.UDPConn) error
Stop()
Stats() (*wireguard.Stats, error)
Stats() (*wgcfg.Stats, error)
}

func newWireguardDevice(tunnelSetup WireguardTunnelSetup) wireguardDevice {
Expand Down Expand Up @@ -235,7 +236,7 @@ func (w *wireguardDeviceImpl) Stop() {
}
}

func (w *wireguardDeviceImpl) Stats() (*wireguard.Stats, error) {
func (w *wireguardDeviceImpl) Stats() (*wgcfg.Stats, error) {
if w.device == nil {
return nil, errors.New("device is not started")
}
Expand All @@ -251,7 +252,7 @@ func (w *wireguardDeviceImpl) Stats() (*wireguard.Stats, error) {
}

func (w *wireguardDeviceImpl) applyConfig(devApi *device.Device, privateKey string, config wireguard.ServiceConfig) error {
deviceConfig := wireguard.DeviceConfig{
deviceConfig := wgcfg.DeviceConfig{
PrivateKey: privateKey,
ListenPort: config.LocalPort,
}
Expand All @@ -260,7 +261,7 @@ func (w *wireguardDeviceImpl) applyConfig(devApi *device.Device, privateKey stri
return err
}

peer := wireguard.Peer{
peer := wgcfg.Peer{
Endpoint: &config.Provider.Endpoint,
PublicKey: config.Provider.PublicKey,
KeepAlivePeriodSeconds: 18,
Expand Down
7 changes: 4 additions & 3 deletions mobile/mysterium/wireguard_connection_setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/mysteriumnetwork/node/core/connection"
"github.com/mysteriumnetwork/node/core/ip"
wg "github.com/mysteriumnetwork/node/services/wireguard"
"github.com/mysteriumnetwork/node/services/wireguard/wgcfg"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -135,14 +136,14 @@ func (m mockWireGuardDevice) Start(_ string, _ wg.ServiceConfig, _ *net.UDPConn)
func (m mockWireGuardDevice) Stop() {
}

func (m mockWireGuardDevice) Stats() (*wg.Stats, error) {
return &wg.Stats{BytesSent: 10, BytesReceived: 11}, nil
func (m mockWireGuardDevice) Stats() (*wgcfg.Stats, error) {
return &wgcfg.Stats{BytesSent: 10, BytesReceived: 11}, nil
}

type mockHandshakeWaiter struct {
err error
}

func (m *mockHandshakeWaiter) Wait(statsFetch func() (*wg.Stats, error), timeout time.Duration, stop <-chan struct{}) error {
func (m *mockHandshakeWaiter) Wait(statsFetch func() (*wgcfg.Stats, error), timeout time.Duration, stop <-chan struct{}) error {
return m.err
}
3 changes: 2 additions & 1 deletion services/wireguard/connection/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/mysteriumnetwork/node/firewall"
wg "github.com/mysteriumnetwork/node/services/wireguard"
"github.com/mysteriumnetwork/node/services/wireguard/key"
"github.com/mysteriumnetwork/node/services/wireguard/wgcfg"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
)
Expand Down Expand Up @@ -127,7 +128,7 @@ func (c *Connection) Start(ctx context.Context, options connection.ConnectOption
PrivateKey: c.privateKey,
IPAddress: config.Consumer.IPAddress,
ListenPort: config.LocalPort,
Peer: wg.Peer{
Peer: wgcfg.Peer{
Endpoint: &config.Provider.Endpoint,
PublicKey: config.Provider.PublicKey,
AllowedIPs: []string{"0.0.0.0/0", "::/0"},
Expand Down
9 changes: 5 additions & 4 deletions services/wireguard/connection/connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/mysteriumnetwork/node/core/connection"
"github.com/mysteriumnetwork/node/core/ip"
wg "github.com/mysteriumnetwork/node/services/wireguard"
"github.com/mysteriumnetwork/node/services/wireguard/wgcfg"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -135,18 +136,18 @@ func (mce *mockConnectionEndpoint) StartProviderMode(config wg.ProviderModeConfi
func (mce *mockConnectionEndpoint) InterfaceName() string { return "mce0" }
func (mce *mockConnectionEndpoint) Stop() error { return nil }
func (mce *mockConnectionEndpoint) Config() (wg.ServiceConfig, error) { return wg.ServiceConfig{}, nil }
func (mce *mockConnectionEndpoint) AddPeer(_ string, _ wg.Peer) error { return nil }
func (mce *mockConnectionEndpoint) AddPeer(_ string, _ wgcfg.Peer) error { return nil }
func (mce *mockConnectionEndpoint) RemovePeer(_ string) error { return nil }
func (mce *mockConnectionEndpoint) ConfigureRoutes(_ net.IP) error { return nil }
func (mce *mockConnectionEndpoint) PeerStats() (*wg.Stats, error) {
return &wg.Stats{LastHandshake: time.Now(), BytesSent: 10, BytesReceived: 11}, nil
func (mce *mockConnectionEndpoint) PeerStats() (*wgcfg.Stats, error) {
return &wgcfg.Stats{LastHandshake: time.Now(), BytesSent: 10, BytesReceived: 11}, nil
}

type mockHandshakeWaiter struct {
err error
}

func (m *mockHandshakeWaiter) Wait(statsFetch func() (*wg.Stats, error), timeout time.Duration, stop <-chan struct{}) error {
func (m *mockHandshakeWaiter) Wait(statsFetch func() (*wgcfg.Stats, error), timeout time.Duration, stop <-chan struct{}) error {
return m.err
}

Expand Down
6 changes: 3 additions & 3 deletions services/wireguard/connection/handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ import (
"net"
"time"

"github.com/mysteriumnetwork/node/services/wireguard"
"github.com/mysteriumnetwork/node/services/wireguard/wgcfg"
)

// HandshakeWaiter waits for handshake.
type HandshakeWaiter interface {
// Wait waits until WireGuard does initial handshake.
Wait(statsFetch func() (*wireguard.Stats, error), timeout time.Duration, stop <-chan struct{}) error
Wait(statsFetch func() (*wgcfg.Stats, error), timeout time.Duration, stop <-chan struct{}) error
}

// NewHandshakeWaiter returns handshake waiter instance.
Expand All @@ -40,7 +40,7 @@ func NewHandshakeWaiter() HandshakeWaiter {
type handshakeWaiter struct {
}

func (h *handshakeWaiter) Wait(statsFetch func() (*wireguard.Stats, error), timeout time.Duration, stop <-chan struct{}) error {
func (h *handshakeWaiter) Wait(statsFetch func() (*wgcfg.Stats, error), timeout time.Duration, stop <-chan struct{}) error {
// We need to send any packet to initialize handshake process.
handshakePingConn, err := net.DialTimeout("tcp", "8.8.8.8:53", 100*time.Millisecond)
if err == nil {
Expand Down
163 changes: 0 additions & 163 deletions services/wireguard/device_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,166 +16,3 @@
*/

package wireguard

import (
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"net"
"strings"
"time"

"github.com/rs/zerolog/log"
)

// Stats represents wireguard peer statistics information.
type Stats struct {
BytesSent uint64 `json:"bytes_sent"`
BytesReceived uint64 `json:"bytes_received"`
LastHandshake time.Time `json:"last_handshake"`
}

// DeviceConfig describes wireguard device configuration.
type DeviceConfig struct {
IfaceName string `json:"iface_name"`
Subnet net.IPNet `json:"subnet"`
PrivateKey string `json:"private_key"`
ListenPort int `json:"listen_port"`

Peer Peer `json:"peer"`
}

// MarshalJSON implements json.Marshaler interface to provide human readable configuration.
func (dc DeviceConfig) MarshalJSON() ([]byte, error) {
type peer struct {
PublicKey string `json:"public_key"`
Endpoint string `json:"endpoint"`
AllowedIPs []string `json:"allowed_i_ps"`
KeepAlivePeriodSeconds int `json:"keep_alive_period_seconds"`
}

type deviceConfig struct {
IfaceName string `json:"iface_name"`
Subnet string `json:"subnet"`
PrivateKey string `json:"private_key"`
ListenPort int `json:"listen_port"`
Peer peer `json:"peer"`
}

var peerEndpoint string
if dc.Peer.Endpoint != nil {
peerEndpoint = dc.Peer.Endpoint.String()
}

return json.Marshal(&deviceConfig{
IfaceName: dc.IfaceName,
Subnet: dc.Subnet.String(),
PrivateKey: dc.PrivateKey,
ListenPort: dc.ListenPort,
Peer: peer{
PublicKey: dc.Peer.PublicKey,
Endpoint: peerEndpoint,
AllowedIPs: dc.Peer.AllowedIPs,
KeepAlivePeriodSeconds: dc.Peer.KeepAlivePeriodSeconds,
},
})
}

// UnmarshalJSON implements json.Unmarshaler interface to receive human readable configuration.
func (dc *DeviceConfig) UnmarshalJSON(data []byte) error {
type peer struct {
PublicKey string `json:"public_key"`
Endpoint string `json:"endpoint"`
AllowedIPs []string `json:"allowed_i_ps"`
KeepAlivePeriodSeconds int `json:"keep_alive_period_seconds"`
}

type deviceConfig struct {
IfaceName string `json:"iface_name"`
Subnet string `json:"subnet"`
PrivateKey string `json:"private_key"`
ListenPort int `json:"listen_port"`
Peer peer `json:"peer"`
}

cfg := deviceConfig{}

if err := json.Unmarshal(data, &cfg); err != nil {
return fmt.Errorf("could not unmarshal device config: %w", err)
}

ip, ipnet, err := net.ParseCIDR(cfg.Subnet)
if err != nil {
return fmt.Errorf("could not parse subnet: %w", err)
}

var peerEndpoint *net.UDPAddr
if cfg.Peer.Endpoint != "" {
peerEndpoint, err = net.ResolveUDPAddr("udp", cfg.Peer.Endpoint)
if err != nil {
return fmt.Errorf("could not resolve peer endpoint: %w", err)
}
}

dc.IfaceName = cfg.IfaceName
dc.Subnet = *ipnet
dc.Subnet.IP = ip
dc.PrivateKey = cfg.PrivateKey
dc.ListenPort = cfg.ListenPort
dc.Peer = Peer{
PublicKey: cfg.Peer.PublicKey,
Endpoint: peerEndpoint,
AllowedIPs: cfg.Peer.AllowedIPs,
KeepAlivePeriodSeconds: cfg.Peer.KeepAlivePeriodSeconds,
}

return nil
}

// Encode encodes device config into string representation which is used for
// userspace and kernel space wireguard configuration.
func (dc *DeviceConfig) Encode() string {
var res strings.Builder
keyBytes, err := base64.StdEncoding.DecodeString(dc.PrivateKey)
if err != nil {
log.Err(err).Msg("Could not decode device private key. Will use empty config.")
return ""
}
hexKey := hex.EncodeToString(keyBytes)

res.WriteString(fmt.Sprintf("private_key=%s\n", hexKey))
res.WriteString(fmt.Sprintf("listen_port=%d\n", dc.ListenPort))
res.WriteString(dc.Peer.Encode())
return res.String()
}

// Peer represents wireguard peer.
type Peer struct {
PublicKey string `json:"public_key"`
Endpoint *net.UDPAddr `json:"endpoint"`
AllowedIPs []string `json:"allowed_i_ps"`
KeepAlivePeriodSeconds int `json:"keep_alive_period_seconds"`
}

// Encode encodes device peer config into string representation which is used for
// userspace and kernel space wireguard configuration.
func (p *Peer) Encode() string {
var res strings.Builder

keyBytes, err := base64.StdEncoding.DecodeString(p.PublicKey)
if err != nil {
log.Err(err).Msg("Could not decode device public key. Will use empty config.")
return ""
}
hexKey := hex.EncodeToString(keyBytes)
res.WriteString(fmt.Sprintf("public_key=%s\n", hexKey))
res.WriteString(fmt.Sprintf("persistent_keepalive_interval=%d\n", p.KeepAlivePeriodSeconds))
if p.Endpoint != nil {
res.WriteString(fmt.Sprintf("endpoint=%s\n", p.Endpoint.String()))
}
for _, ip := range p.AllowedIPs {
res.WriteString(fmt.Sprintf("allowed_ip=%s\n", ip))
}
return res.String()
}
Loading

0 comments on commit 924532c

Please sign in to comment.