Move network settings to ad-hoc screen
Can now set gateway/DNS/proxy settings explicitly. - Read from .ovpn (hosts only) - Pull from server (PUSH_REPLY) - Set manually
This commit is contained in:
parent
bab8e28b04
commit
c6fbdca342
|
@ -233,6 +233,7 @@
|
|||
<segue destination="NJT-2N-LTa" kind="show" identifier="HostParametersSegueIdentifier" id="aL8-H6-znA"/>
|
||||
<segue destination="9Kr-G1-asf" kind="show" identifier="ProviderPresetSegueIdentifier" id="kGf-Yu-KdY"/>
|
||||
<segue destination="KmS-dJ-DVx" kind="show" identifier="DebugLogSegueIdentifier" id="XyI-by-AhD"/>
|
||||
<segue destination="BCT-c7-ovS" kind="show" identifier="NetworkSettingsSegueIdentifier" id="5nM-PM-q9h"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
|
@ -384,6 +385,67 @@
|
|||
</objects>
|
||||
<point key="canvasLocation" x="1622" y="-270"/>
|
||||
</scene>
|
||||
<!--Network Settings View Controller-->
|
||||
<scene sceneID="BPW-VO-Hgb">
|
||||
<objects>
|
||||
<tableViewController id="BCT-c7-ovS" customClass="NetworkSettingsViewController" customModule="Passepartout" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="qQL-jO-j0W">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="SettingTableViewCell" textLabel="NYG-Gq-hRp" detailTextLabel="iDZ-BL-Un5" style="IBUITableViewCellStyleValue1" id="KTK-qM-Z3I" customClass="SettingTableViewCell" customModule="Passepartout" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="KTK-qM-Z3I" id="pZZ-fb-3Rb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="NYG-Gq-hRp">
|
||||
<rect key="frame" x="16" y="12" width="33.5" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Detail" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="iDZ-BL-Un5">
|
||||
<rect key="frame" x="315" y="12" width="44" height="20.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="FieldTableViewCell" textLabel="chG-HK-4WY" style="IBUITableViewCellStyleDefault" id="JNm-q5-qBn" customClass="FieldTableViewCell" customModule="Passepartout" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="99.5" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="JNm-q5-qBn" id="NG6-Jk-qkq">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="chG-HK-4WY">
|
||||
<rect key="frame" x="16" y="0.0" width="343" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="BCT-c7-ovS" id="b8X-oR-HW4"/>
|
||||
<outlet property="delegate" destination="BCT-c7-ovS" id="L7V-gR-mRb"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="MWy-o4-Doa" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-1098" y="1042"/>
|
||||
</scene>
|
||||
<!--Debug Log View Controller-->
|
||||
<scene sceneID="Icu-BA-Eze">
|
||||
<objects>
|
||||
|
|
|
@ -21,6 +21,7 @@ internal enum StoryboardSegue {
|
|||
case debugLogSegueIdentifier = "DebugLogSegueIdentifier"
|
||||
case endpointSegueIdentifier = "EndpointSegueIdentifier"
|
||||
case hostParametersSegueIdentifier = "HostParametersSegueIdentifier"
|
||||
case networkSettingsSegueIdentifier = "NetworkSettingsSegueIdentifier"
|
||||
case providerPoolSegueIdentifier = "ProviderPoolSegueIdentifier"
|
||||
case providerPresetSegueIdentifier = "ProviderPresetSegueIdentifier"
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ class ConfigurationViewController: UIViewController, TableModelHost {
|
|||
}
|
||||
model.add(.tls)
|
||||
model.add(.compression)
|
||||
model.add(.network)
|
||||
// model.add(.network)
|
||||
model.add(.other)
|
||||
|
||||
// headers
|
||||
|
|
|
@ -0,0 +1,613 @@
|
|||
//
|
||||
// NetworkSettingsViewController.swift
|
||||
// Passepartout-iOS
|
||||
//
|
||||
// Created by Davide De Rosa on 4/29/19.
|
||||
// Copyright (c) 2019 Davide De Rosa. All rights reserved.
|
||||
//
|
||||
// https://github.com/passepartoutvpn
|
||||
//
|
||||
// This file is part of Passepartout.
|
||||
//
|
||||
// Passepartout is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Passepartout is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Passepartout_Core
|
||||
import TunnelKit
|
||||
import SwiftyBeaver
|
||||
|
||||
private let log = SwiftyBeaver.self
|
||||
|
||||
private enum FieldTag: Int {
|
||||
case dnsDomain = 101
|
||||
|
||||
case dnsAddress = 200
|
||||
|
||||
case proxyAddress = 301
|
||||
|
||||
case proxyPort = 302
|
||||
|
||||
case proxyBypass = 400
|
||||
}
|
||||
|
||||
private struct Offsets {
|
||||
static let dnsAddress = 1
|
||||
|
||||
static let proxyBypass = 2
|
||||
}
|
||||
|
||||
// FIXME: init networkSettings with HOST profile.sessionConfiguration
|
||||
// FIXME: omit "Client" for PROVIDER
|
||||
|
||||
class NetworkSettingsViewController: UITableViewController {
|
||||
var profile: ConnectionProfile?
|
||||
|
||||
private lazy var networkChoices: ProfileNetworkChoices = {
|
||||
if let choices = profile?.networkChoices {
|
||||
return choices
|
||||
}
|
||||
if let _ = profile as? ProviderConnectionProfile {
|
||||
return ProfileNetworkChoices(choice: .server)
|
||||
}
|
||||
return ProfileNetworkChoices(choice: .client)
|
||||
}()
|
||||
|
||||
private let networkSettings = ProfileNetworkSettings()
|
||||
|
||||
private lazy var clientNetworkSettings: ProfileNetworkSettings? = {
|
||||
guard let hostProfile = profile as? HostConnectionProfile else {
|
||||
return nil
|
||||
}
|
||||
return ProfileNetworkSettings(from: hostProfile.parameters.sessionConfiguration)
|
||||
}()
|
||||
|
||||
private var choices: [NetworkChoice] {
|
||||
guard let _ = clientNetworkSettings else {
|
||||
return [.server, .manual]
|
||||
}
|
||||
return [.client, .server, .manual]
|
||||
}
|
||||
|
||||
// MARK: TableModelHost
|
||||
|
||||
let model: TableModel<SectionType, RowType> = TableModel()
|
||||
|
||||
func reloadModel() {
|
||||
model.clear()
|
||||
|
||||
// sections
|
||||
model.add(.choices)
|
||||
if networkChoices.gateway != .server {
|
||||
model.add(.manualGateway)
|
||||
}
|
||||
if networkChoices.dns != .server {
|
||||
model.add(.manualDNS)
|
||||
}
|
||||
if networkChoices.proxy != .server {
|
||||
model.add(.manualProxy)
|
||||
}
|
||||
|
||||
// headers
|
||||
model.setHeader("", for: .choices)
|
||||
model.setHeader(L10n.Configuration.Cells.DefaultGateway.caption, for: .manualGateway)
|
||||
model.setHeader(L10n.Configuration.Cells.DnsServer.caption, for: .manualDNS)
|
||||
model.setHeader(L10n.Configuration.Cells.ProxyHttp.caption, for: .manualProxy)
|
||||
|
||||
// footers
|
||||
// model.setFooter(L10n.Configuration.Sections.Reset.footer, for: .reset)
|
||||
|
||||
// rows
|
||||
model.set([.gateway, .dns, .proxy], in: .choices)
|
||||
model.set([.gatewayAll, .gatewayIPv4, .gatewayIPv6, .gatewayNone], in: .manualGateway)
|
||||
|
||||
var dnsRows: [RowType] = Array(repeating: .dnsAddress, count: networkSettings.dnsServers?.count ?? 0)
|
||||
dnsRows.insert(.dnsDomain, at: 0)
|
||||
if networkChoices.dns == .manual {
|
||||
dnsRows.append(.dnsAddAddress)
|
||||
}
|
||||
model.set(dnsRows, in: .manualDNS)
|
||||
|
||||
var proxyRows: [RowType] = Array(repeating: .proxyBypass, count: networkSettings.proxyBypassDomains?.count ?? 0)
|
||||
proxyRows.insert(.proxyAddress, at: 0)
|
||||
proxyRows.insert(.proxyPort, at: 1)
|
||||
if networkChoices.proxy == .manual {
|
||||
proxyRows.append(.proxyAddBypass)
|
||||
}
|
||||
model.set(proxyRows, in: .manualProxy)
|
||||
}
|
||||
|
||||
// MARK: UIViewController
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
updateGateway(networkChoices.gateway)
|
||||
updateDNS(networkChoices.dns)
|
||||
updateProxy(networkChoices.proxy)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
reloadModel()
|
||||
tableView.reloadData()
|
||||
}
|
||||
|
||||
override func viewDidDisappear(_ animated: Bool) {
|
||||
super.viewDidDisappear(animated)
|
||||
|
||||
profile?.networkChoices = networkChoices
|
||||
if networkChoices.gateway == .manual {
|
||||
let settings = profile?.manualNetworkSettings ?? ProfileNetworkSettings()
|
||||
settings.copyGateway(from: networkSettings)
|
||||
profile?.manualNetworkSettings = settings
|
||||
}
|
||||
if networkChoices.dns == .manual {
|
||||
let settings = profile?.manualNetworkSettings ?? ProfileNetworkSettings()
|
||||
settings.copyDNS(from: networkSettings)
|
||||
profile?.manualNetworkSettings = settings
|
||||
}
|
||||
if networkChoices.proxy == .manual {
|
||||
let settings = profile?.manualNetworkSettings ?? ProfileNetworkSettings()
|
||||
settings.copyProxy(from: networkSettings)
|
||||
profile?.manualNetworkSettings = settings
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Actions
|
||||
|
||||
private func updateGateway(_ choice: NetworkChoice) {
|
||||
networkChoices.gateway = choice
|
||||
switch networkChoices.gateway {
|
||||
case .client:
|
||||
if let settings = clientNetworkSettings {
|
||||
networkSettings.copyGateway(from: settings)
|
||||
}
|
||||
|
||||
case .server:
|
||||
break
|
||||
|
||||
case .manual:
|
||||
if let settings = profile?.manualNetworkSettings {
|
||||
networkSettings.copyGateway(from: settings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func updateDNS(_ choice: NetworkChoice) {
|
||||
networkChoices.dns = choice
|
||||
switch networkChoices.dns {
|
||||
case .client:
|
||||
if let settings = clientNetworkSettings {
|
||||
networkSettings.copyDNS(from: settings)
|
||||
}
|
||||
|
||||
case .server:
|
||||
break
|
||||
|
||||
case .manual:
|
||||
if let settings = profile?.manualNetworkSettings {
|
||||
networkSettings.copyDNS(from: settings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func updateProxy(_ choice: NetworkChoice) {
|
||||
networkChoices.proxy = choice
|
||||
switch networkChoices.proxy {
|
||||
case .client:
|
||||
if let settings = clientNetworkSettings {
|
||||
networkSettings.copyProxy(from: settings)
|
||||
}
|
||||
|
||||
case .server:
|
||||
break
|
||||
|
||||
case .manual:
|
||||
if let settings = profile?.manualNetworkSettings {
|
||||
networkSettings.copyProxy(from: settings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func commitTextField(_ field: UITextField) {
|
||||
|
||||
// DNS: domain, servers
|
||||
// Proxy: address, port, bypass domains
|
||||
|
||||
if field.tag == FieldTag.dnsDomain.rawValue {
|
||||
networkSettings.dnsDomainName = field.text
|
||||
} else if field.tag == FieldTag.proxyAddress.rawValue {
|
||||
networkSettings.proxyAddress = field.text
|
||||
} else if field.tag == FieldTag.proxyPort.rawValue {
|
||||
networkSettings.proxyPort = UInt16(field.text ?? "0")
|
||||
} else if field.tag >= FieldTag.dnsAddress.rawValue && field.tag < FieldTag.proxyAddress.rawValue {
|
||||
let i = field.tag - FieldTag.dnsAddress.rawValue
|
||||
networkSettings.dnsServers?[i] = field.text ?? ""
|
||||
} else if field.tag >= FieldTag.proxyBypass.rawValue {
|
||||
let i = field.tag - FieldTag.proxyBypass.rawValue
|
||||
networkSettings.proxyBypassDomains?[i] = field.text ?? ""
|
||||
}
|
||||
|
||||
log.debug("Network settings: \(networkSettings)")
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
extension NetworkSettingsViewController {
|
||||
enum SectionType: Int {
|
||||
case choices
|
||||
|
||||
case manualGateway
|
||||
|
||||
case manualDNS
|
||||
|
||||
case manualProxy
|
||||
}
|
||||
|
||||
enum RowType: Int {
|
||||
case gateway
|
||||
|
||||
case dns
|
||||
|
||||
case proxy
|
||||
|
||||
case gatewayAll
|
||||
|
||||
case gatewayIPv4
|
||||
|
||||
case gatewayIPv6
|
||||
|
||||
case gatewayNone
|
||||
|
||||
case dnsDomain
|
||||
|
||||
case dnsAddress
|
||||
|
||||
case dnsAddAddress
|
||||
|
||||
case proxyAddress
|
||||
|
||||
case proxyPort
|
||||
|
||||
case proxyBypass
|
||||
|
||||
case proxyAddBypass
|
||||
}
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return model.count
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
return model.header(for: section)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
|
||||
return model.footer(for: section)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
||||
return model.headerHeight(for: section)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return model.count(for: section)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let row = model.row(at: indexPath)
|
||||
|
||||
switch row {
|
||||
case .gateway:
|
||||
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
|
||||
cell.leftText = model.header(for: .manualGateway)
|
||||
cell.rightText = networkChoices.gateway.description
|
||||
return cell
|
||||
|
||||
case .dns:
|
||||
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
|
||||
cell.leftText = model.header(for: .manualDNS)
|
||||
cell.rightText = networkChoices.dns.description
|
||||
return cell
|
||||
|
||||
case .proxy:
|
||||
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
|
||||
cell.leftText = model.header(for: .manualProxy)
|
||||
cell.rightText = networkChoices.proxy.description
|
||||
return cell
|
||||
|
||||
case .gatewayAll, .gatewayIPv4, .gatewayIPv6, .gatewayNone:
|
||||
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
|
||||
var policies: [SessionProxy.RoutingPolicy]?
|
||||
|
||||
switch row {
|
||||
case .gatewayAll:
|
||||
cell.leftText = L10n.Global.Cells.enabled
|
||||
policies = [.IPv4, .IPv6]
|
||||
|
||||
case .gatewayIPv4:
|
||||
cell.leftText = "IPv4"
|
||||
policies = [.IPv4]
|
||||
|
||||
case .gatewayIPv6:
|
||||
cell.leftText = "IPv6"
|
||||
policies = [.IPv6]
|
||||
|
||||
case .gatewayNone:
|
||||
cell.leftText = L10n.Global.Cells.disabled
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
cell.applyChecked(networkSettings.gatewayPolicies == policies, Theme.current)
|
||||
cell.isTappable = (networkChoices.gateway == .manual)
|
||||
return cell
|
||||
|
||||
case .dnsDomain:
|
||||
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
|
||||
cell.caption = L10n.Configuration.Cells.DnsDomain.caption
|
||||
cell.field.tag = FieldTag.dnsDomain.rawValue
|
||||
cell.field.text = networkSettings.dnsDomainName
|
||||
cell.field.clearButtonMode = .always
|
||||
cell.field.keyboardType = .asciiCapable
|
||||
cell.captionWidth = 160.0
|
||||
cell.delegate = self
|
||||
if networkChoices.dns == .manual {
|
||||
cell.field.isEnabled = true
|
||||
cell.field.placeholder = "example.com"
|
||||
} else {
|
||||
cell.field.isEnabled = false
|
||||
cell.field.placeholder = nil
|
||||
}
|
||||
return cell
|
||||
|
||||
case .dnsAddress:
|
||||
let i = indexPath.row - Offsets.dnsAddress
|
||||
|
||||
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
|
||||
cell.caption = L10n.NetworkSettings.Cells.Address.caption
|
||||
cell.field.tag = FieldTag.dnsAddress.rawValue + i
|
||||
cell.field.text = networkSettings.dnsServers?[i]
|
||||
cell.field.clearButtonMode = .always
|
||||
cell.field.keyboardType = .decimalPad
|
||||
cell.captionWidth = 160.0
|
||||
cell.delegate = self
|
||||
if networkChoices.dns == .manual {
|
||||
cell.field.isEnabled = true
|
||||
cell.field.placeholder = "8.8.8.8"
|
||||
} else {
|
||||
cell.field.isEnabled = false
|
||||
cell.field.placeholder = nil
|
||||
}
|
||||
return cell
|
||||
|
||||
case .dnsAddAddress:
|
||||
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
|
||||
cell.applyAction(Theme.current)
|
||||
cell.leftText = L10n.NetworkSettings.Cells.AddDnsServer.caption
|
||||
return cell
|
||||
|
||||
case .proxyAddress:
|
||||
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
|
||||
cell.caption = L10n.NetworkSettings.Cells.Address.caption
|
||||
cell.field.tag = FieldTag.proxyAddress.rawValue
|
||||
cell.field.text = networkSettings.proxyAddress
|
||||
cell.field.clearButtonMode = .always
|
||||
cell.field.keyboardType = .decimalPad
|
||||
cell.captionWidth = 160.0
|
||||
cell.delegate = self
|
||||
if networkChoices.proxy == .manual {
|
||||
cell.field.isEnabled = true
|
||||
cell.field.placeholder = "192.168.1.1"
|
||||
} else {
|
||||
cell.field.isEnabled = false
|
||||
cell.field.placeholder = nil
|
||||
}
|
||||
return cell
|
||||
|
||||
case .proxyPort:
|
||||
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
|
||||
cell.caption = L10n.NetworkSettings.Cells.Port.caption
|
||||
cell.field.tag = FieldTag.proxyPort.rawValue
|
||||
cell.field.text = networkSettings.proxyPort?.description
|
||||
cell.field.clearButtonMode = .always
|
||||
cell.field.keyboardType = .numberPad
|
||||
cell.captionWidth = 160.0
|
||||
cell.delegate = self
|
||||
if networkChoices.proxy == .manual {
|
||||
cell.field.isEnabled = true
|
||||
cell.field.placeholder = "8080"
|
||||
} else {
|
||||
cell.field.isEnabled = false
|
||||
cell.field.placeholder = nil
|
||||
}
|
||||
return cell
|
||||
|
||||
case .proxyBypass:
|
||||
let i = indexPath.row - Offsets.proxyBypass
|
||||
|
||||
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
|
||||
cell.caption = L10n.NetworkSettings.Cells.ProxyBypass.caption
|
||||
cell.field.tag = FieldTag.proxyBypass.rawValue + i
|
||||
cell.field.text = networkSettings.proxyBypassDomains?[i]
|
||||
cell.field.clearButtonMode = .always
|
||||
cell.field.keyboardType = .asciiCapable
|
||||
cell.captionWidth = 160.0
|
||||
cell.delegate = self
|
||||
if networkChoices.proxy == .manual {
|
||||
cell.field.isEnabled = true
|
||||
cell.field.placeholder = "excluded.com"
|
||||
} else {
|
||||
cell.field.isEnabled = false
|
||||
cell.field.placeholder = nil
|
||||
}
|
||||
return cell
|
||||
|
||||
case .proxyAddBypass:
|
||||
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
|
||||
cell.applyAction(Theme.current)
|
||||
cell.leftText = L10n.NetworkSettings.Cells.AddProxyBypass.caption
|
||||
return cell
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let cell = tableView.cellForRow(at: indexPath)
|
||||
|
||||
switch model.row(at: indexPath) {
|
||||
case .gateway:
|
||||
let vc = OptionViewController<NetworkChoice>()
|
||||
vc.title = (cell as? SettingTableViewCell)?.leftText
|
||||
vc.options = choices
|
||||
vc.descriptionBlock = { $0.description }
|
||||
|
||||
vc.selectedOption = networkChoices.gateway
|
||||
vc.selectionBlock = { [weak self] in
|
||||
self?.updateGateway($0)
|
||||
self?.navigationController?.popViewController(animated: true)
|
||||
}
|
||||
navigationController?.pushViewController(vc, animated: true)
|
||||
|
||||
case .dns:
|
||||
let vc = OptionViewController<NetworkChoice>()
|
||||
vc.title = (cell as? SettingTableViewCell)?.leftText
|
||||
vc.options = choices
|
||||
vc.descriptionBlock = { $0.description }
|
||||
|
||||
vc.selectedOption = networkChoices.dns
|
||||
vc.selectionBlock = { [weak self] in
|
||||
self?.updateDNS($0)
|
||||
self?.navigationController?.popViewController(animated: true)
|
||||
}
|
||||
navigationController?.pushViewController(vc, animated: true)
|
||||
|
||||
case .proxy:
|
||||
let vc = OptionViewController<NetworkChoice>()
|
||||
vc.title = (cell as? SettingTableViewCell)?.leftText
|
||||
vc.options = choices
|
||||
vc.descriptionBlock = { $0.description }
|
||||
|
||||
vc.selectedOption = networkChoices.proxy
|
||||
vc.selectionBlock = { [weak self] in
|
||||
self?.updateProxy($0)
|
||||
self?.navigationController?.popViewController(animated: true)
|
||||
}
|
||||
navigationController?.pushViewController(vc, animated: true)
|
||||
|
||||
case .gatewayAll:
|
||||
guard networkChoices.gateway == .manual else {
|
||||
return
|
||||
}
|
||||
networkSettings.gatewayPolicies = [.IPv4, .IPv6]
|
||||
tableView.reloadData()
|
||||
|
||||
case .gatewayIPv4:
|
||||
guard networkChoices.gateway == .manual else {
|
||||
return
|
||||
}
|
||||
networkSettings.gatewayPolicies = [.IPv4]
|
||||
tableView.reloadData()
|
||||
|
||||
case .gatewayIPv6:
|
||||
guard networkChoices.gateway == .manual else {
|
||||
return
|
||||
}
|
||||
networkSettings.gatewayPolicies = [.IPv6]
|
||||
tableView.reloadData()
|
||||
|
||||
case .gatewayNone:
|
||||
guard networkChoices.gateway == .manual else {
|
||||
return
|
||||
}
|
||||
networkSettings.gatewayPolicies = nil
|
||||
tableView.reloadData()
|
||||
|
||||
case .dnsAddAddress:
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
|
||||
var dnsServers = networkSettings.dnsServers ?? []
|
||||
dnsServers.append("")
|
||||
networkSettings.dnsServers = dnsServers
|
||||
reloadModel()
|
||||
tableView.insertRows(at: [indexPath], with: .automatic)
|
||||
|
||||
case .proxyAddBypass:
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
|
||||
var bypassDomains = networkSettings.proxyBypassDomains ?? []
|
||||
bypassDomains.append("")
|
||||
networkSettings.proxyBypassDomains = bypassDomains
|
||||
reloadModel()
|
||||
tableView.insertRows(at: [indexPath], with: .automatic)
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
|
||||
switch model.row(at: indexPath) {
|
||||
case .dnsAddress, .proxyBypass:
|
||||
return true
|
||||
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
|
||||
switch model.row(at: indexPath) {
|
||||
case .dnsAddress:
|
||||
// start at row 1
|
||||
networkSettings.dnsServers?.remove(at: indexPath.row - Offsets.dnsAddress)
|
||||
|
||||
case .proxyBypass:
|
||||
// start at row 2
|
||||
networkSettings.proxyBypassDomains?.remove(at: indexPath.row - Offsets.proxyBypass)
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
reloadModel()
|
||||
tableView.deleteRows(at: [indexPath], with: .automatic)
|
||||
}
|
||||
}
|
||||
|
||||
extension NetworkSettingsViewController: FieldTableViewCellDelegate {
|
||||
func fieldCellDidEdit(_ cell: FieldTableViewCell) {
|
||||
commitTextField(cell.field)
|
||||
}
|
||||
|
||||
func fieldCellDidEnter(_: FieldTableViewCell) {
|
||||
}
|
||||
}
|
||||
|
||||
extension NetworkChoice: CustomStringConvertible {
|
||||
public var description: String {
|
||||
switch self {
|
||||
case .client:
|
||||
return L10n.NetworkSettings.Cells.Choice.client
|
||||
|
||||
case .server:
|
||||
return L10n.NetworkSettings.Cells.Choice.server
|
||||
|
||||
case .manual:
|
||||
return L10n.Global.Cells.manual
|
||||
}
|
||||
}
|
||||
}
|
|
@ -174,6 +174,11 @@ class ServiceViewController: UIViewController, TableModelHost {
|
|||
vc?.originalConfigurationURL = service.configurationURL(for: uncheckedHostProfile)
|
||||
vc?.delegate = self
|
||||
|
||||
case .networkSettingsSegueIdentifier:
|
||||
let vc = destination as? NetworkSettingsViewController
|
||||
vc?.title = L10n.Service.Cells.NetworkSettings.caption
|
||||
vc?.profile = profile
|
||||
|
||||
case .debugLogSegueIdentifier:
|
||||
break
|
||||
}
|
||||
|
@ -580,6 +585,8 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
|
|||
|
||||
case hostParameters
|
||||
|
||||
case networkSettings
|
||||
|
||||
case vpnResolvesHostname
|
||||
|
||||
case vpnSurvivesSleep
|
||||
|
@ -720,6 +727,11 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
|
|||
}
|
||||
return cell
|
||||
|
||||
case .networkSettings:
|
||||
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
|
||||
cell.leftText = L10n.Service.Cells.NetworkSettings.caption
|
||||
return cell
|
||||
|
||||
// provider cells
|
||||
|
||||
case .providerPool:
|
||||
|
@ -908,6 +920,10 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
|
|||
perform(segue: StoryboardSegue.Main.hostParametersSegueIdentifier, sender: cell)
|
||||
return true
|
||||
|
||||
case .networkSettings:
|
||||
perform(segue: StoryboardSegue.Main.networkSettingsSegueIdentifier, sender: cell)
|
||||
return true
|
||||
|
||||
case .trustedAddCurrentWiFi:
|
||||
if #available(iOS 12, *) {
|
||||
IntentDispatcher.donateTrustCurrentNetwork()
|
||||
|
@ -1059,10 +1075,10 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
|
|||
}
|
||||
if isProvider {
|
||||
model.set([.account], in: .authentication)
|
||||
model.set([.providerPool, .endpoint, .providerPreset], in: .configuration)
|
||||
model.set([.providerPool, .endpoint, .providerPreset, .networkSettings], in: .configuration)
|
||||
model.set([.providerRefresh], in: .providerInfrastructure)
|
||||
} else {
|
||||
model.set([.account, .endpoint, .hostParameters], in: .configuration)
|
||||
model.set([.account, .endpoint, .hostParameters, .networkSettings], in: .configuration)
|
||||
}
|
||||
if isActiveProfile {
|
||||
if isProvider {
|
||||
|
|
|
@ -110,6 +110,8 @@
|
|||
0EF56BBB2185AC8500B0C8AB /* SwiftGen+Segues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EF56BBA2185AC8500B0C8AB /* SwiftGen+Segues.swift */; };
|
||||
0EF5CF252141CE58004FF1BD /* HUD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EF5CF242141CE58004FF1BD /* HUD.swift */; };
|
||||
0EF5CF292141F31F004FF1BD /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E4FD7ED20D539A0002221FF /* Utils.swift */; };
|
||||
0EFB901822764689006405E4 /* ProfileNetworkSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFB901722764689006405E4 /* ProfileNetworkSettings.swift */; };
|
||||
0EFB901A2276D7F1006405E4 /* NetworkSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFB90192276D7F1006405E4 /* NetworkSettingsViewController.swift */; };
|
||||
0EFBFAC121AC464800887A8C /* CreditsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFBFAC021AC464800887A8C /* CreditsViewController.swift */; };
|
||||
0EFD943E215BE10800529B64 /* IssueReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFD943D215BE10800529B64 /* IssueReporter.swift */; };
|
||||
0EFD9440215BED8E00529B64 /* LabelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFD943F215BED8E00529B64 /* LabelViewController.swift */; };
|
||||
|
@ -286,6 +288,8 @@
|
|||
0EEB53B1225D525B00746300 /* Downloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Downloader.swift; sourceTree = "<group>"; };
|
||||
0EF56BBA2185AC8500B0C8AB /* SwiftGen+Segues.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SwiftGen+Segues.swift"; sourceTree = "<group>"; };
|
||||
0EF5CF242141CE58004FF1BD /* HUD.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HUD.swift; sourceTree = "<group>"; };
|
||||
0EFB901722764689006405E4 /* ProfileNetworkSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileNetworkSettings.swift; sourceTree = "<group>"; };
|
||||
0EFB90192276D7F1006405E4 /* NetworkSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkSettingsViewController.swift; sourceTree = "<group>"; };
|
||||
0EFBFAC021AC464800887A8C /* CreditsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreditsViewController.swift; sourceTree = "<group>"; };
|
||||
0EFD943D215BE10800529B64 /* IssueReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IssueReporter.swift; sourceTree = "<group>"; };
|
||||
0EFD943F215BED8E00529B64 /* LabelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -510,6 +514,7 @@
|
|||
0EC7F20420E24308004EA58E /* DebugLog.swift */,
|
||||
0ED38AE621404F100004D387 /* EndpointDataSource.swift */,
|
||||
0E89DFC4213DF7AE00741BA1 /* Preferences.swift */,
|
||||
0EFB901722764689006405E4 /* ProfileNetworkSettings.swift */,
|
||||
0E89DFC7213E8FC500741BA1 /* SessionProxy+Communication.swift */,
|
||||
0E2B494120FD16540094784C /* TransientStore.swift */,
|
||||
0E4C9CB820DB9BC600A0C59C /* TrustedNetworks.swift */,
|
||||
|
@ -610,6 +615,7 @@
|
|||
0E1D72B3213C118500BA1586 /* ConfigurationViewController.swift */,
|
||||
0E6BE13E20CFBAB300A6DD36 /* DebugLogViewController.swift */,
|
||||
0E158AD920E11B0B00C85A82 /* EndpointViewController.swift */,
|
||||
0EFB90192276D7F1006405E4 /* NetworkSettingsViewController.swift */,
|
||||
0ED31C2B20CF2D6F0027975F /* ProviderPoolViewController.swift */,
|
||||
0E1D72B1213BFFCF00BA1586 /* ProviderPresetViewController.swift */,
|
||||
0E57F63D20C83FC5008323CF /* ServiceViewController.swift */,
|
||||
|
@ -1047,6 +1053,7 @@
|
|||
0E58BD9322404EF1006FB157 /* Intents.intentdefinition in Sources */,
|
||||
0E3152D3223FA05400F61841 /* EndpointDataSource.swift in Sources */,
|
||||
0E3152D4223FA05400F61841 /* Preferences.swift in Sources */,
|
||||
0EFB901822764689006405E4 /* ProfileNetworkSettings.swift in Sources */,
|
||||
0E3152C0223FA03D00F61841 /* Utils.swift in Sources */,
|
||||
0E3152CB223FA04D00F61841 /* Pool.swift in Sources */,
|
||||
0E3152C7223FA04800F61841 /* VPNStatus.swift in Sources */,
|
||||
|
@ -1075,6 +1082,7 @@
|
|||
0E4FD7F120D58618002221FF /* Macros.swift in Sources */,
|
||||
0EF5CF252141CE58004FF1BD /* HUD.swift in Sources */,
|
||||
0E05C5D720D1645F006EE732 /* ToggleTableViewCell.swift in Sources */,
|
||||
0EFB901A2276D7F1006405E4 /* NetworkSettingsViewController.swift in Sources */,
|
||||
0E05C5D420D1645F006EE732 /* FieldTableViewCell.swift in Sources */,
|
||||
0E36D25C224034AD006AF062 /* ShortcutsConnectToViewController.swift in Sources */,
|
||||
0E05C61D20D27C82006EE732 /* Theme.swift in Sources */,
|
||||
|
|
|
@ -109,6 +109,7 @@
|
|||
"service.cells.provider.preset.caption" = "Preset";
|
||||
"service.cells.provider.refresh.caption" = "Refresh infrastructure";
|
||||
"service.cells.host.parameters.caption" = "Parameters";
|
||||
"service.cells.network_settings.caption" = "Network settings";
|
||||
"service.cells.vpn_survives_sleep.caption" = "Keep alive on sleep";
|
||||
"service.cells.vpn_resolves_hostname.caption" = "Resolve server hostname";
|
||||
//"service.cells.vpn_prefers_udp.caption" = "Prefer UDP socket";
|
||||
|
@ -200,6 +201,14 @@
|
|||
"configuration.cells.renegotiation_seconds.value.after" = "after %@";
|
||||
"configuration.cells.random_endpoint.caption" = "Randomize endpoint";
|
||||
|
||||
"network_settings.cells.choice.client" = "Read .ovpn";
|
||||
"network_settings.cells.choice.server" = "Pull from server";
|
||||
"network_settings.cells.address.caption" = "Address";
|
||||
"network_settings.cells.port.caption" = "Port";
|
||||
"network_settings.cells.add_dns_server.caption" = "Add address";
|
||||
"network_settings.cells.proxy_bypass.caption" = "Bypass domain";
|
||||
"network_settings.cells.add_proxy_bypass.caption" = "Add bypass domain";
|
||||
|
||||
"debug_log.buttons.previous" = "Previous";
|
||||
"debug_log.buttons.next" = "Next";
|
||||
"debug_log.alerts.empty_log.message" = "The debug log is empty.";
|
||||
|
|
|
@ -42,6 +42,10 @@ public protocol ConnectionProfile: class, EndpointDataSource, CustomStringConver
|
|||
|
||||
var requiresCredentials: Bool { get }
|
||||
|
||||
var networkChoices: ProfileNetworkChoices? { get set }
|
||||
|
||||
var manualNetworkSettings: ProfileNetworkSettings? { get set }
|
||||
|
||||
func generate(from configuration: TunnelKitProvider.Configuration, preferences: Preferences) throws -> TunnelKitProvider.Configuration
|
||||
|
||||
func with(newId: String) -> ConnectionProfile
|
||||
|
|
|
@ -299,6 +299,7 @@ public class ConnectionService: Codable {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return profile
|
||||
}
|
||||
|
||||
|
@ -531,7 +532,19 @@ public class ConnectionService: Codable {
|
|||
}
|
||||
}
|
||||
|
||||
let cfg = try profile.generate(from: baseConfiguration, preferences: preferences)
|
||||
var cfg = try profile.generate(from: baseConfiguration, preferences: preferences)
|
||||
|
||||
// override network settings
|
||||
if let choices = profile.networkChoices, let settings = profile.manualNetworkSettings {
|
||||
var builder = cfg.builder()
|
||||
var sessionBuilder = builder.sessionConfiguration.builder()
|
||||
sessionBuilder.applyGateway(from: choices, settings: settings)
|
||||
sessionBuilder.applyDNS(from: choices, settings: settings)
|
||||
sessionBuilder.applyProxy(from: choices, settings: settings)
|
||||
builder.sessionConfiguration = sessionBuilder.build()
|
||||
cfg = builder.build()
|
||||
}
|
||||
|
||||
let protocolConfiguration = try cfg.generatedTunnelProtocol(
|
||||
withBundleIdentifier: GroupConstants.App.tunnelIdentifier,
|
||||
appGroup: appGroup,
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
//
|
||||
// ProfileNetworkSettings.swift
|
||||
// Passepartout
|
||||
//
|
||||
// Created by Davide De Rosa on 04/28/19.
|
||||
// Copyright (c) 2019 Davide De Rosa. All rights reserved.
|
||||
//
|
||||
// https://github.com/passepartoutvpn
|
||||
//
|
||||
// This file is part of Passepartout.
|
||||
//
|
||||
// Passepartout is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Passepartout is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import TunnelKit
|
||||
|
||||
public enum NetworkChoice: String, Codable {
|
||||
case client
|
||||
|
||||
case server // erase client settings
|
||||
|
||||
case manual
|
||||
}
|
||||
|
||||
public class ProfileNetworkChoices: Codable {
|
||||
public var gateway: NetworkChoice
|
||||
|
||||
public var dns: NetworkChoice
|
||||
|
||||
public var proxy: NetworkChoice
|
||||
|
||||
public init(choice: NetworkChoice) {
|
||||
gateway = choice
|
||||
dns = choice
|
||||
proxy = choice
|
||||
}
|
||||
}
|
||||
|
||||
public class ProfileNetworkSettings: Codable, CustomStringConvertible {
|
||||
public var gatewayPolicies: [SessionProxy.RoutingPolicy]?
|
||||
|
||||
public var dnsServers: [String]?
|
||||
|
||||
public var dnsDomainName: String?
|
||||
|
||||
public var proxyAddress: String?
|
||||
|
||||
public var proxyPort: UInt16?
|
||||
|
||||
public var proxyServer: Proxy? {
|
||||
guard let address = proxyAddress, let port = proxyPort, !address.isEmpty, port > 0 else {
|
||||
return nil
|
||||
}
|
||||
return Proxy(address, port)
|
||||
}
|
||||
|
||||
public var proxyBypassDomains: [String]?
|
||||
|
||||
public init() {
|
||||
gatewayPolicies = [.IPv4, .IPv6]
|
||||
}
|
||||
|
||||
public init(from configuration: SessionProxy.Configuration) {
|
||||
gatewayPolicies = configuration.routingPolicies
|
||||
dnsDomainName = configuration.searchDomain
|
||||
dnsServers = configuration.dnsServers
|
||||
proxyAddress = configuration.httpProxy?.address
|
||||
proxyPort = configuration.httpProxy?.port
|
||||
proxyBypassDomains = configuration.proxyBypassDomains
|
||||
}
|
||||
|
||||
public func copy(from settings: ProfileNetworkSettings) {
|
||||
copyGateway(from: settings)
|
||||
copyDNS(from: settings)
|
||||
copyProxy(from: settings)
|
||||
}
|
||||
|
||||
public func copyGateway(from settings: ProfileNetworkSettings) {
|
||||
gatewayPolicies = settings.gatewayPolicies
|
||||
}
|
||||
|
||||
public func copyDNS(from settings: ProfileNetworkSettings) {
|
||||
dnsDomainName = settings.dnsDomainName
|
||||
dnsServers = settings.dnsServers?.filter { !$0.isEmpty }
|
||||
}
|
||||
|
||||
public func copyProxy(from settings: ProfileNetworkSettings) {
|
||||
proxyAddress = settings.proxyAddress
|
||||
proxyPort = settings.proxyPort
|
||||
proxyBypassDomains = settings.proxyBypassDomains?.filter { !$0.isEmpty }
|
||||
}
|
||||
|
||||
// MARK: CustomStringConvertible
|
||||
|
||||
public var description: String {
|
||||
let comps: [String] = [
|
||||
"gw: \(gatewayPolicies?.description ?? "")",
|
||||
"dns: {domain: \(dnsDomainName ?? ""), servers: \(dnsServers?.description ?? "[]")}",
|
||||
"proxy: {address: \(proxyAddress ?? ""), port: \(proxyPort?.description ?? ""), bypass: \(proxyBypassDomains?.description ?? "[]")}"
|
||||
]
|
||||
return "{\(comps.joined(separator: ", "))}"
|
||||
}
|
||||
}
|
||||
|
||||
extension SessionProxy.ConfigurationBuilder {
|
||||
public mutating func applyGateway(from choices: ProfileNetworkChoices, settings: ProfileNetworkSettings) {
|
||||
switch choices.gateway {
|
||||
case .client:
|
||||
break
|
||||
|
||||
case .server:
|
||||
routingPolicies = nil
|
||||
|
||||
case .manual:
|
||||
routingPolicies = settings.gatewayPolicies
|
||||
}
|
||||
}
|
||||
|
||||
public mutating func applyDNS(from choices: ProfileNetworkChoices, settings: ProfileNetworkSettings) {
|
||||
switch choices.dns {
|
||||
case .client:
|
||||
break
|
||||
|
||||
case .server:
|
||||
dnsServers = nil
|
||||
searchDomain = nil
|
||||
|
||||
case .manual:
|
||||
dnsServers = settings.dnsServers?.filter { !$0.isEmpty }
|
||||
searchDomain = settings.dnsDomainName
|
||||
}
|
||||
}
|
||||
|
||||
public mutating func applyProxy(from choices: ProfileNetworkChoices, settings: ProfileNetworkSettings) {
|
||||
switch choices.proxy {
|
||||
case .client:
|
||||
break
|
||||
|
||||
case .server:
|
||||
httpProxy = nil
|
||||
httpsProxy = nil
|
||||
proxyBypassDomains = nil
|
||||
|
||||
case .manual:
|
||||
if let proxyServer = settings.proxyServer {
|
||||
httpProxy = proxyServer
|
||||
httpsProxy = proxyServer
|
||||
proxyBypassDomains = settings.proxyBypassDomains?.filter { !$0.isEmpty }
|
||||
} else {
|
||||
httpProxy = nil
|
||||
httpsProxy = nil
|
||||
proxyBypassDomains = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -54,6 +54,10 @@ public class HostConnectionProfile: ConnectionProfile, Codable, Equatable {
|
|||
return false
|
||||
}
|
||||
|
||||
public var networkChoices: ProfileNetworkChoices?
|
||||
|
||||
public var manualNetworkSettings: ProfileNetworkSettings?
|
||||
|
||||
public func generate(from configuration: TunnelKitProvider.Configuration, preferences: Preferences) throws -> TunnelKitProvider.Configuration {
|
||||
guard let endpointProtocols = parameters.sessionConfiguration.endpointProtocols, !endpointProtocols.isEmpty else {
|
||||
preconditionFailure("No endpointProtocols")
|
||||
|
|
|
@ -35,6 +35,10 @@ public class PlaceholderConnectionProfile: ConnectionProfile {
|
|||
|
||||
public var requiresCredentials: Bool = false
|
||||
|
||||
public var networkChoices: ProfileNetworkChoices?
|
||||
|
||||
public var manualNetworkSettings: ProfileNetworkSettings?
|
||||
|
||||
public func generate(from configuration: TunnelKitProvider.Configuration, preferences: Preferences) throws -> TunnelKitProvider.Configuration {
|
||||
fatalError("Generating configuration from a PlaceholderConnectionProfile")
|
||||
}
|
||||
|
|
|
@ -57,6 +57,10 @@ public class ProviderConnectionProfile: ConnectionProfile, Codable, Equatable {
|
|||
|
||||
public var manualProtocol: EndpointProtocol?
|
||||
|
||||
public var networkChoices: ProfileNetworkChoices?
|
||||
|
||||
public var manualNetworkSettings: ProfileNetworkSettings?
|
||||
|
||||
public var usesProviderEndpoint: Bool {
|
||||
return (manualAddress != nil) || (manualProtocol != nil)
|
||||
}
|
||||
|
|
|
@ -417,6 +417,37 @@ public enum L10n {
|
|||
}
|
||||
}
|
||||
|
||||
public enum NetworkSettings {
|
||||
public enum Cells {
|
||||
public enum AddDnsServer {
|
||||
/// Add address
|
||||
public static let caption = L10n.tr("Localizable", "network_settings.cells.add_dns_server.caption")
|
||||
}
|
||||
public enum AddProxyBypass {
|
||||
/// Add bypass domain
|
||||
public static let caption = L10n.tr("Localizable", "network_settings.cells.add_proxy_bypass.caption")
|
||||
}
|
||||
public enum Address {
|
||||
/// Address
|
||||
public static let caption = L10n.tr("Localizable", "network_settings.cells.address.caption")
|
||||
}
|
||||
public enum Choice {
|
||||
/// Read .ovpn
|
||||
public static let client = L10n.tr("Localizable", "network_settings.cells.choice.client")
|
||||
/// Pull from server
|
||||
public static let server = L10n.tr("Localizable", "network_settings.cells.choice.server")
|
||||
}
|
||||
public enum Port {
|
||||
/// Port
|
||||
public static let caption = L10n.tr("Localizable", "network_settings.cells.port.caption")
|
||||
}
|
||||
public enum ProxyBypass {
|
||||
/// Bypass domain
|
||||
public static let caption = L10n.tr("Localizable", "network_settings.cells.proxy_bypass.caption")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Organizer {
|
||||
public enum Alerts {
|
||||
public enum AddHost {
|
||||
|
@ -699,6 +730,10 @@ public enum L10n {
|
|||
/// Mask network data
|
||||
public static let caption = L10n.tr("Localizable", "service.cells.masks_private_data.caption")
|
||||
}
|
||||
public enum NetworkSettings {
|
||||
/// Network settings
|
||||
public static let caption = L10n.tr("Localizable", "service.cells.network_settings.caption")
|
||||
}
|
||||
public enum Provider {
|
||||
public enum Pool {
|
||||
/// Location
|
||||
|
|
Loading…
Reference in New Issue