Skip to content

Commit

Permalink
Wait for device to be available
Browse files Browse the repository at this point in the history
  • Loading branch information
jyyi1 committed Dec 6, 2024
1 parent 7586b48 commit ed601b4
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 15 deletions.
6 changes: 3 additions & 3 deletions client/electron/vpn_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,19 @@ export async function establishVpn(request: StartRequestJson) {
const config: EstablishVpnRequest = {
id: currentRequestId,

// TUN device name, compatible with old code:
// TUN device name, being compatible with old code:
// https://github.com/Jigsaw-Code/outline-apps/blob/client/linux/v1.14.0/client/electron/linux_proxy_controller/outline_proxy_controller.h#L203
interfaceName: 'outline-tun0',

// Network Manager connection name, Use "TUN Connection" instead of "VPN Connection"
// because Network Manager has a dedicated "VPN Connection" concept that we did not implement
connectionName: 'Outline TUN Connection',

// TUN IP, compatible with old code:
// TUN IP, being compatible with old code:
// https://github.com/Jigsaw-Code/outline-apps/blob/client/linux/v1.14.0/client/electron/linux_proxy_controller/outline_proxy_controller.h#L204
ipAddress: '10.0.85.1',

// DNS server list, compatible with old code:
// DNS server list, being compatible with old code:
// https://github.com/Jigsaw-Code/outline-apps/blob/client/linux/v1.14.0/client/electron/linux_proxy_controller/outline_proxy_controller.h#L207
dnsServers: ['9.9.9.9'],

Expand Down
6 changes: 4 additions & 2 deletions client/go/outline/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ func (d *Device) Close() (err error) {
}

func (d *Device) RefreshConnectivity() (err error) {
slog.Debug("[Outine] Testing connectivity of Outline server ...")
result := CheckTCPAndUDPConnectivity(d.c)
if result.TCPError != nil {
slog.Warn("[Outline] Outline server connectivity test failed", "err", result.TCPError)
return result.TCPError
}

Expand All @@ -97,7 +99,7 @@ func (d *Device) RefreshConnectivity() (err error) {
slog.Warn("[Outline] server cannot handle UDP traffic", "err", result.UDPError)
proxy = d.fallback
} else {
slog.Info("[Outline] server can handle UDP traffic")
slog.Debug("[Outline] server can handle UDP traffic")
proxy = d.remote
canHandleUDP = true
}
Expand All @@ -112,7 +114,7 @@ func (d *Device) RefreshConnectivity() (err error) {
}
}
d.supportsUDP = &canHandleUDP
slog.Info("[OutlineNetDev] UDP handler refreshed", "supportsUDP", canHandleUDP)
slog.Info("[Outline] Outline server connectivity test done", "supportsUDP", canHandleUDP)
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion client/go/outline/method_channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const (
type Handler func(string) (string, error)

// handlers is a map of registered handlers.
var handlers map[string]Handler
var handlers = make(map[string]Handler)

// RegisterMethodHandler registers a native function handler for the given method.
//
Expand Down
31 changes: 22 additions & 9 deletions client/go/outline/vpn/nmconn_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"encoding/binary"
"log/slog"
"net"
"time"

gonm "github.com/Wifx/gonetworkmanager/v2"
"golang.org/x/sys/unix"
Expand Down Expand Up @@ -45,7 +46,7 @@ func (c *linuxVPNConn) establishNMConnection() (err error) {
}
slog.Debug(nmLogPfx + "connected")

dev, err := c.nm.GetDeviceByIpIface(c.nmOpts.TUNName)
dev, err := c.waitForDeviceToBeAvailable()
if err != nil {
return errSetupVPN(nmLogPfx, "failed to find TUN device", err, "tun", c.nmOpts.TUNName)
}
Expand Down Expand Up @@ -94,6 +95,18 @@ func (c *linuxVPNConn) closeNMConnection() error {
return nil
}

func (c *linuxVPNConn) waitForDeviceToBeAvailable() (dev gonm.Device, err error) {
for retries := 20; retries > 0; retries-- {
dev, err = c.nm.GetDeviceByIpIface(c.nmOpts.TUNName)
if dev != nil && err == nil {
return
}
slog.Warn(nmLogPfx+"waiting for TUN device to be available", "err", err)
time.Sleep(50 * time.Millisecond)
}
return nil, errSetupVPN(nmLogPfx, "failed to find TUN device", err, "tun", c.nmOpts.TUNName)
}

func configureCommonProps(props map[string]map[string]interface{}, opts *nmConnectionOptions) {
props["connection"] = map[string]interface{}{
"id": opts.Name,
Expand All @@ -102,20 +115,20 @@ func configureCommonProps(props map[string]map[string]interface{}, opts *nmConne
}

func configureTUNProps(props map[string]map[string]interface{}) {
props["tun"] = make(map[string]interface{})

// The operating mode of the virtual device.
// Allowed values are 1 (tun) to create a layer 3 device and 2 (tap) to create an Ethernet-like layer 2 one.
props["tun"]["mode"] = uint32(1)
props["tun"] = map[string]interface{}{
// The operating mode of the virtual device.
// Allowed values are 1 (tun) to create a layer 3 device and 2 (tap) to create an Ethernet-like layer 2 one.
"mode": uint32(1),
}
}

func configureIPv4Props(props map[string]map[string]interface{}, opts *nmConnectionOptions) {
props["ipv4"] = make(map[string]interface{})
props["ipv4"]["method"] = "manual"
props["ipv4"] = map[string]interface{}{
"method": "manual",
}

// Array of IPv4 addresses. Each address dictionary contains at least 'address' and 'prefix' entries,
// containing the IP address as a string, and the prefix length as a uint32.

addr := make(map[string]interface{})
addr["address"] = opts.TUNAddr.To4().String()
addr["prefix"] = uint32(32)
Expand Down

0 comments on commit ed601b4

Please sign in to comment.