VPN: TunnelsManager should keep track of tunnel names to prevent duplicate names

Signed-off-by: Roopesh Chander <roop@roopc.net>
This commit is contained in:
Roopesh Chander 2018-10-31 17:03:32 +05:30
parent fff1a70ab9
commit 0aab067a53
1 changed files with 17 additions and 0 deletions

View File

@ -30,21 +30,25 @@ class TunnelsManager {
private var isModifyingTunnel: Bool = false private var isModifyingTunnel: Bool = false
private var isDeletingTunnel: Bool = false private var isDeletingTunnel: Bool = false
private var tunnelNames: Set<String>
private var currentTunnel: TunnelContainer? private var currentTunnel: TunnelContainer?
private var currentTunnelStatusObservationToken: AnyObject? private var currentTunnelStatusObservationToken: AnyObject?
init(tunnelProviders: [NETunnelProviderManager]) { init(tunnelProviders: [NETunnelProviderManager]) {
var tunnelNames: Set<String> = []
var tunnels = tunnelProviders.map { TunnelContainer(tunnel: $0, index: 0) } var tunnels = tunnelProviders.map { TunnelContainer(tunnel: $0, index: 0) }
tunnels.sort { $0.name < $1.name } tunnels.sort { $0.name < $1.name }
var currentTunnel: TunnelContainer? = nil var currentTunnel: TunnelContainer? = nil
for i in 0 ..< tunnels.count { for i in 0 ..< tunnels.count {
let tunnel = tunnels[i] let tunnel = tunnels[i]
tunnel.index = i tunnel.index = i
tunnelNames.insert(tunnel.name)
if (tunnel.status != .inactive) { if (tunnel.status != .inactive) {
currentTunnel = tunnel currentTunnel = tunnel
} }
} }
self.tunnels = tunnels self.tunnels = tunnels
self.tunnelNames = tunnelNames
if let currentTunnel = currentTunnel { if let currentTunnel = currentTunnel {
setCurrentTunnel(tunnel: currentTunnel) setCurrentTunnel(tunnel: currentTunnel)
} }
@ -60,6 +64,10 @@ class TunnelsManager {
} }
} }
func containsTunnel(named name: String) -> Bool {
return tunnelNames.contains(name)
}
private func insertionIndexFor(tunnelName: String) -> Int { private func insertionIndexFor(tunnelName: String) -> Int {
// Wishlist: Use binary search instead // Wishlist: Use binary search instead
for i in 0 ..< tunnels.count { for i in 0 ..< tunnels.count {
@ -71,6 +79,7 @@ class TunnelsManager {
func add(tunnelConfiguration: TunnelConfiguration, completionHandler: @escaping (TunnelContainer?, Error?) -> Void) { func add(tunnelConfiguration: TunnelConfiguration, completionHandler: @escaping (TunnelContainer?, Error?) -> Void) {
let tunnelName = tunnelConfiguration.interface.name let tunnelName = tunnelConfiguration.interface.name
assert(!tunnelName.isEmpty) assert(!tunnelName.isEmpty)
assert(!containsTunnel(named: tunnelName))
isAddingTunnel = true isAddingTunnel = true
let tunnelProviderManager = NETunnelProviderManager() let tunnelProviderManager = NETunnelProviderManager()
@ -91,6 +100,7 @@ class TunnelsManager {
s.tunnels[i].index = s.tunnels[i].index + 1 s.tunnels[i].index = s.tunnels[i].index + 1
} }
s.tunnels.insert(tunnel, at: index) s.tunnels.insert(tunnel, at: index)
s.tunnelNames.insert(tunnel.name)
s.delegate?.tunnelAdded(at: index) s.delegate?.tunnelAdded(at: index)
completionHandler(tunnel, nil) completionHandler(tunnel, nil)
} }
@ -126,7 +136,10 @@ class TunnelsManager {
let tunnelProviderManager = tunnel.tunnelProvider let tunnelProviderManager = tunnel.tunnelProvider
let isNameChanged = (tunnelName != tunnelProviderManager.localizedDescription) let isNameChanged = (tunnelName != tunnelProviderManager.localizedDescription)
var oldName: String? = nil
if (isNameChanged) { if (isNameChanged) {
assert(!containsTunnel(named: tunnelName))
oldName = tunnel.name
tunnel.name = tunnelName tunnel.name = tunnelName
} }
tunnelProviderManager.protocolConfiguration = NETunnelProviderProtocol(tunnelConfiguration: tunnelConfiguration) tunnelProviderManager.protocolConfiguration = NETunnelProviderProtocol(tunnelConfiguration: tunnelConfiguration)
@ -142,6 +155,7 @@ class TunnelsManager {
if let s = self { if let s = self {
if (isNameChanged) { if (isNameChanged) {
s.tunnels.remove(at: tunnel.index) s.tunnels.remove(at: tunnel.index)
s.tunnelNames.remove(oldName!)
for i in tunnel.index ..< s.tunnels.count { for i in tunnel.index ..< s.tunnels.count {
s.tunnels[i].index = s.tunnels[i].index - 1 s.tunnels[i].index = s.tunnels[i].index - 1
} }
@ -151,6 +165,7 @@ class TunnelsManager {
s.tunnels[i].index = s.tunnels[i].index + 1 s.tunnels[i].index = s.tunnels[i].index + 1
} }
s.tunnels.insert(tunnel, at: index) s.tunnels.insert(tunnel, at: index)
s.tunnelNames.insert(tunnel.name)
s.delegate?.tunnelsChanged() s.delegate?.tunnelsChanged()
} else { } else {
s.delegate?.tunnelModified(at: tunnel.index) s.delegate?.tunnelModified(at: tunnel.index)
@ -163,6 +178,7 @@ class TunnelsManager {
func remove(tunnel: TunnelContainer, completionHandler: @escaping (Error?) -> Void) { func remove(tunnel: TunnelContainer, completionHandler: @escaping (Error?) -> Void) {
let tunnelProviderManager = tunnel.tunnelProvider let tunnelProviderManager = tunnel.tunnelProvider
let tunnelIndex = tunnel.index let tunnelIndex = tunnel.index
let tunnelName = tunnel.name
isDeletingTunnel = true isDeletingTunnel = true
@ -177,6 +193,7 @@ class TunnelsManager {
s.tunnels[i].index = s.tunnels[i].index + 1 s.tunnels[i].index = s.tunnels[i].index + 1
} }
s.tunnels.remove(at: tunnelIndex) s.tunnels.remove(at: tunnelIndex)
s.tunnelNames.remove(tunnelName)
s.delegate?.tunnelRemoved(at: tunnelIndex) s.delegate?.tunnelRemoved(at: tunnelIndex)
} }
completionHandler(nil) completionHandler(nil)