Skip to content

Commit

Permalink
Update comments for VPN package
Browse files Browse the repository at this point in the history
  • Loading branch information
jyyi1 committed Dec 16, 2024
1 parent 134331a commit b05140d
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 12 deletions.
8 changes: 8 additions & 0 deletions client/go/outline/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
"github.com/Jigsaw-Code/outline-sdk/network/lwip2transport"
)

// Device is an IPDevice that connects to a remote Outline server.
// It also implements the vpn.ProxyDevice interface.
type Device struct {
network.IPDevice

Expand All @@ -38,17 +40,21 @@ type Device struct {

var _ vpn.ProxyDevice = (*Device)(nil)

// NewDevice creates a new [Device] using the given [Client].
func NewDevice(c *Client) (*Device, error) {
if c == nil {
return nil, errors.New("Client must be provided")
}
return &Device{c: c}, nil
}

// SupportsUDP returns true if the the Outline server forwards UDP traffic.
// This value will be refreshed after Connect or RefreshConnectivity.
func (d *Device) SupportsUDP() bool {
return d.supportsUDP
}

// Connect tries to connect to the Outline server.
func (d *Device) Connect(ctx context.Context) (err error) {
if ctx.Err() != nil {
return perrs.PlatformError{Code: perrs.OperationCanceled}
Expand Down Expand Up @@ -78,13 +84,15 @@ func (d *Device) Connect(ctx context.Context) (err error) {
return nil
}

// Close closes the connection to the Outline server.
func (d *Device) Close() (err error) {
if d.IPDevice != nil {
err = d.IPDevice.Close()
}
return
}

// RefreshConnectivity refreshes the connectivity to the Outline server.
func (d *Device) RefreshConnectivity(ctx context.Context) (err error) {
if ctx.Err() != nil {
return perrs.PlatformError{Code: perrs.OperationCanceled}
Expand Down
7 changes: 7 additions & 0 deletions client/go/outline/vpn.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ type vpnConfigJSON struct {
TransportConfig string `json:"transport"`
}

// establishVPN establishes a VPN connection using the given configuration string.
// The configuration string should be a JSON object containing the VPN configuration
// and the transport configuration.
//
// The function returns a JSON string representing the established VPN connection,
// or an error if the connection fails.
func establishVPN(configStr string) (string, error) {
var conf vpnConfigJSON
if err := json.Unmarshal([]byte(configStr), &conf); err != nil {
Expand Down Expand Up @@ -77,6 +83,7 @@ func establishVPN(configStr string) (string, error) {
return string(connJson), nil
}

// closeVPN closes the currently active VPN connection.
func closeVPN() error {
return vpn.CloseVPN()
}
1 change: 1 addition & 0 deletions client/go/outline/vpn/dialer.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ package vpn

import "syscall"

// ControlFn is an alias to a function type that can be used in net.Dialer.Control.
type ControlFn = func(network, address string, c syscall.RawConn) error
4 changes: 4 additions & 0 deletions client/go/outline/vpn/dialer_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"syscall"
)

// TCPDialerControl returns a ControlFn that sets the SO_MARK socket option on a TCP connection.
// This is used to exclude traffic targeting the remote proxy server from routing to TUN device.
func TCPDialerControl(conf *Config) (ControlFn, error) {
if conf == nil {
return nil, errors.New("VPN config must be provided")
Expand All @@ -30,6 +32,8 @@ func TCPDialerControl(conf *Config) (ControlFn, error) {
}, nil
}

// TCPDialerControl returns a ControlFn that sets the SO_MARK socket option on a TCP connection.
// This is used to exclude traffic targeting the remote proxy server from routing to TUN device.
func UDPDialerControl(conf *Config) (ControlFn, error) {
return TCPDialerControl(conf)
}
2 changes: 2 additions & 0 deletions client/go/outline/vpn/dialer_others.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ package vpn

import "errors"

// TCPDialerControl is not supported on this platform.
func TCPDialerControl(conf *Config) (ControlFn, error) {
return nil, errors.ErrUnsupported
}

// UDPDialerControl is not supported on this platform.
func UDPDialerControl(conf *Config) (ControlFn, error) {
return nil, errors.ErrUnsupported
}
28 changes: 22 additions & 6 deletions client/go/outline/vpn/vpn.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/Jigsaw-Code/outline-sdk/network"
)

// Config holds the configuration to establish a system-wide [VPNConnection].
type Config struct {
ID string `json:"id"`
InterfaceName string `json:"interfaceName"`
Expand All @@ -35,7 +36,7 @@ type Config struct {
ProtectionMark uint32 `json:"protectionMark"`
}

// Status defines the possible states of a VPN connection.
// Status defines the possible states of a [VPNConnection].
type Status string

// Constants representing the different VPN connection statuses.
Expand All @@ -47,20 +48,33 @@ const (
StatusDisconnecting Status = "Disconnecting"
)

// ProxyDevice is an interface representing a remote proxy server device.
type ProxyDevice interface {
network.IPDevice

// Connect establishes a connection to the proxy device.
Connect(ctx context.Context) error

// SupportsUDP returns true if the proxy device is able to handle UDP traffic.
SupportsUDP() bool

// RefreshConnectivity refreshes the UDP support of the proxy device.
RefreshConnectivity(ctx context.Context) error
}

// platformVPNConn is an interface representing an OS-specific VPN connection.
type platformVPNConn interface {
// Establish creates a TUN device and routes all system traffic to it.
Establish(ctx context.Context) error

// TUN returns a L3 IP tun device associated with the VPN connection.
TUN() io.ReadWriteCloser

// Close terminates the VPN connection and closes the TUN device.
Close() error
}

// VPNConnection is a platform neutral interface of a VPN connection.
// VPNConnection represents a system-wide VPN connection.
type VPNConnection struct {
ID string `json:"id"`
Status Status `json:"status"`
Expand All @@ -74,10 +88,12 @@ type VPNConnection struct {
platform platformVPNConn
}

// SetStatus sets the status of the VPN connection.
func (c *VPNConnection) SetStatus(s Status) {
c.Status = s
}

// SetSupportsUDP sets whether the VPN connection supports UDP.
func (c *VPNConnection) SetSupportsUDP(v bool) {
c.SupportsUDP = &v
}
Expand All @@ -87,10 +103,10 @@ func (c *VPNConnection) SetSupportsUDP(v bool) {
var mu sync.Mutex
var conn *VPNConnection

// EstablishVPN establishes a new active [VPNConnection] with the given configuration.
// It will first close any active [VPNConnection] using [CloseVPN], and then mark the
// EstablishVPN establishes a new active [VPNConnection] with the given [Config].
// It first closes any active [VPNConnection] using [CloseVPN], and then marks the
// newly created [VPNConnection] as the currently active connection.
// It returns the connectionJSON as a string, or an error if the connection fails.
// It returns the new [VPNConnection], or an error if the connection fails.
func EstablishVPN(conf *Config, proxy ProxyDevice) (_ *VPNConnection, err error) {
if conf == nil {
return nil, errors.New("a VPN Config must be provided")
Expand Down Expand Up @@ -157,7 +173,7 @@ func EstablishVPN(conf *Config, proxy ProxyDevice) (_ *VPNConnection, err error)
return c, nil
}

// CloseVPN closes the currently active [VPNConnection].
// CloseVPN terminates the currently active [VPNConnection].
func CloseVPN() error {
mu.Lock()
defer mu.Unlock()
Expand Down
12 changes: 6 additions & 6 deletions client/go/outline/vpn/vpn_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
gonm "github.com/Wifx/gonetworkmanager/v2"
)

// linuxVPNConn implements a [VPNConnection] on Linux platform.
// linuxVPNConn implements a platformVPNConn on the Linux platform.
type linuxVPNConn struct {
tun io.ReadWriteCloser
nmOpts *nmConnectionOptions
Expand All @@ -34,9 +34,8 @@ type linuxVPNConn struct {

var _ platformVPNConn = (*linuxVPNConn)(nil)

// newVPNConnection creates a new Linux specific [VPNConnection].
// The newly connection will be [StatusDisconnected] initially, you need to call the
// Establish() in order to make it [StatusConnected].
// newPlatformVPNConn creates a new Linux-specific platformVPNConn.
// You need to call Establish() in order to make it connected.
func newPlatformVPNConn(conf *Config) (_ platformVPNConn, err error) {
c := &linuxVPNConn{
nmOpts: &nmConnectionOptions{
Expand Down Expand Up @@ -70,9 +69,10 @@ func newPlatformVPNConn(conf *Config) (_ platformVPNConn, err error) {
return c, nil
}

// TUN returns the Linux L3 TUN device.
func (c *linuxVPNConn) TUN() io.ReadWriteCloser { return c.tun }

// Establish tries to establish this [VPNConnection], and makes it [StatusConnected].
// Establish tries to create the TUN device and route all traffic to it.
func (c *linuxVPNConn) Establish(ctx context.Context) (err error) {
if ctx.Err() != nil {
return perrs.PlatformError{Code: perrs.OperationCanceled}
Expand All @@ -89,7 +89,7 @@ func (c *linuxVPNConn) Establish(ctx context.Context) (err error) {
return nil
}

// Close tries to close this [VPNConnection] and make it [StatusDisconnected].
// Close tries to restore the routing and deletes the TUN device.
func (c *linuxVPNConn) Close() (err error) {
if c == nil {
return nil
Expand Down

0 comments on commit b05140d

Please sign in to comment.