Skip to content

Commit

Permalink
Merge pull request #1988 from mysteriumnetwork/proxy-mobile-openvpn
Browse files Browse the repository at this point in the history
Proxy consumer OpenVPN for mobile
  • Loading branch information
zolia authored Apr 2, 2020
2 parents 2653ca9 + 5910f9a commit 37a2ded
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 18 deletions.
38 changes: 29 additions & 9 deletions mobile/mysterium/openvpn_connection_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ type openvpnConnection struct {
natPinger natPinger
ipResolver ip.Resolver
stopOnce sync.Once
stopProxy chan struct{}
}

var _ connection.Connection = &openvpnConnection{}
Expand Down Expand Up @@ -154,8 +155,30 @@ func (c *openvpnConnection) Start(options connection.ConnectOptions) error {
return err
}

// TODO this backward compatibility block needs to be removed once we will fully migrate to the p2p communication.
if len(sessionConfig.Ports) > 0 {
if options.ProviderNATConn != nil {
port, err := port.NewPool().Acquire()
if err != nil {
return errors.Wrap(err, "failed to acquire free port")
}

sessionConfig.LocalPort = port.Num()
sessionConfig.RemoteIP = "127.0.0.1"
sessionConfig.RemotePort = sessionConfig.LocalPort

// Exclude p2p channel traffic from VPN tunnel.
channelSocket, err := peekLookAtSocketFd4From(options.ChannelConn)
if err != nil {
return fmt.Errorf("could not get channel socket: %w", err)
}

proxy := traversal.NewNATProxy()

c.tunnelSetup.SocketProtect(channelSocket)
proxy.SetProtectSocketCallback(c.tunnelSetup.SocketProtect)

localAddr := fmt.Sprintf("127.0.0.1:%d", sessionConfig.LocalPort)
c.stopProxy = proxy.ConsumerHandOff(localAddr, options.ProviderNATConn)
} else if len(sessionConfig.Ports) > 0 { // TODO this backward compatibility block needs to be removed once we will fully migrate to the p2p communication.
if len(sessionConfig.Ports) == 0 || len(c.ports) == 0 {
c.ports = []int{sessionConfig.LocalPort}
sessionConfig.Ports = []int{sessionConfig.RemotePort}
Expand All @@ -172,13 +195,6 @@ func (c *openvpnConnection) Start(options connection.ConnectOptions) error {

c.natPinger.SetProtectSocketCallback(c.tunnelSetup.SocketProtect)

// Exclude p2p channel traffic from VPN tunnel.
channelSocket, err := peekLookAtSocketFd4From(options.ChannelConn)
if err != nil {
return fmt.Errorf("could not get channel socket: %w", err)
}
c.tunnelSetup.SocketProtect(channelSocket)

remoteIP := sessionConfig.RemoteIP
_, _, err = c.natPinger.PingProvider(remoteIP, c.ports, sessionConfig.Ports, sessionConfig.LocalPort)
if err != nil {
Expand Down Expand Up @@ -206,6 +222,10 @@ func (c *openvpnConnection) Stop() {
if c.session != nil {
c.session.Stop()
}

if c.stopProxy != nil {
close(c.stopProxy)
}
})
}

Expand Down
6 changes: 3 additions & 3 deletions nat/traversal/nat_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ type natProxy struct {
}

// NewNATProxy constructs an instance of natProxy
func newNATProxy() *natProxy {
func NewNATProxy() *natProxy {
return &natProxy{
servicePorts: make(map[string]int),
}
}

func (np *natProxy) consumerHandOff(consumerAddr string, remoteConn *net.UDPConn) chan struct{} {
func (np *natProxy) ConsumerHandOff(consumerAddr string, remoteConn *net.UDPConn) chan struct{} {
stop := make(chan struct{})
if np.socketProtect == nil {
// shutdown pinger session since openvpn client will connect directly (without natProxy)
Expand Down Expand Up @@ -204,6 +204,6 @@ func (np *natProxy) isAvailable(key string) bool {
return np.servicePorts[key] > 0
}

func (np *natProxy) setProtectSocketCallback(socketProtect func(socket int) bool) {
func (np *natProxy) SetProtectSocketCallback(socketProtect func(socket int) bool) {
np.socketProtect = socketProtect
}
6 changes: 3 additions & 3 deletions nat/traversal/pinger.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func NewPinger(pingConfig *PingConfig, publisher eventbus.Publisher) NATPinger {
pingConfig: pingConfig,
stop: make(chan struct{}),
stopNATProxy: make(chan struct{}),
natProxy: newNATProxy(),
natProxy: NewNATProxy(),
eventPublisher: publisher,
}
}
Expand Down Expand Up @@ -141,7 +141,7 @@ func (p *Pinger) PingProvider(ip string, localPorts, remotePorts []int, proxyPor
consumerAddr := fmt.Sprintf("127.0.0.1:%d", proxyPort)
log.Info().Msg("Handing connection to consumer NATProxy: " + consumerAddr)

p.stopNATProxy = p.natProxy.consumerHandOff(consumerAddr, conn)
p.stopNATProxy = p.natProxy.ConsumerHandOff(consumerAddr, conn)
} else {
conn.Close()
}
Expand Down Expand Up @@ -434,7 +434,7 @@ func (p *Pinger) pingReceiver(conn *net.UDPConn, stop <-chan struct{}) (*net.UDP

// SetProtectSocketCallback sets socket protection callback to be called when new socket is created in consumer NATProxy
func (p *Pinger) SetProtectSocketCallback(socketProtect func(socket int) bool) {
p.natProxy.setProtectSocketCallback(socketProtect)
p.natProxy.SetProtectSocketCallback(socketProtect)
}

// Valid returns that this pinger is a valid pinger
Expand Down
4 changes: 2 additions & 2 deletions services/openvpn/client_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,11 @@ func NewClientConfigFromSession(vpnConfig VPNConfig, configDir string, runtimeDi
}

var remotePort, localPort int
if options.ProviderNATConn != nil {
if options.ProviderNATConn != nil && vpnConfig.RemoteIP != "127.0.0.1" {
options.ProviderNATConn.Close()
remotePort = options.ProviderNATConn.RemoteAddr().(*net.UDPAddr).Port
localPort = options.ProviderNATConn.LocalAddr().(*net.UDPAddr).Port
} else { // TODO this block needs to be removed once most of the nodes will be using p2p communication.
} else {
remotePort = vpnConfig.RemotePort
localPort = vpnConfig.LocalPort
}
Expand Down
1 change: 0 additions & 1 deletion services/wireguard/connection/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ func (c *Connection) Start(options connection.ConnectOptions) (err error) {
c.stateCh <- connection.Connecting

if options.ProviderNATConn != nil {

options.ProviderNATConn.Close()
config.LocalPort = options.ProviderNATConn.LocalAddr().(*net.UDPAddr).Port
config.Provider.Endpoint.Port = options.ProviderNATConn.RemoteAddr().(*net.UDPAddr).Port
Expand Down

0 comments on commit 37a2ded

Please sign in to comment.