wireguard-apple/WireGuard/Shared/Model/Endpoint.swift

101 lines
3.0 KiB
Swift
Raw Normal View History

2018-10-24 01:37:28 +00:00
// SPDX-License-Identifier: MIT
2019-01-02 00:56:33 +00:00
// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
2018-10-19 14:03:17 +00:00
import Foundation
import Network
struct Endpoint {
let host: NWEndpoint.Host
let port: NWEndpoint.Port
2018-12-21 22:34:56 +00:00
2018-12-21 04:52:45 +00:00
init(host: NWEndpoint.Host, port: NWEndpoint.Port) {
self.host = host
self.port = port
}
2018-10-19 14:03:17 +00:00
}
2018-12-22 04:41:54 +00:00
extension Endpoint: Equatable {
static func == (lhs: Endpoint, rhs: Endpoint) -> Bool {
return lhs.host == rhs.host && lhs.port == rhs.port
}
}
extension Endpoint: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(host)
hasher.combine(port)
}
}
2018-10-19 14:03:17 +00:00
extension Endpoint {
2018-12-21 04:52:45 +00:00
var stringRepresentation: String {
switch host {
case .name(let hostname, _):
return "\(hostname):\(port)"
case .ipv4(let address):
return "\(address):\(port)"
case .ipv6(let address):
return "[\(address)]:\(port)"
@unknown default:
fatalError()
2018-12-21 04:52:45 +00:00
}
}
2018-12-21 22:34:56 +00:00
2018-10-19 14:03:17 +00:00
init?(from string: String) {
// Separation of host and port is based on 'parse_endpoint' function in
// https://git.zx2c4.com/WireGuard/tree/src/tools/config.c
guard !string.isEmpty else { return nil }
let startOfPort: String.Index
let hostString: String
if string.first! == "[" {
2018-10-19 14:03:17 +00:00
// Look for IPv6-style endpoint, like [::1]:80
let startOfHost = string.index(after: string.startIndex)
guard let endOfHost = string.dropFirst().firstIndex(of: "]") else { return nil }
let afterEndOfHost = string.index(after: endOfHost)
guard string[afterEndOfHost] == ":" else { return nil }
startOfPort = string.index(after: afterEndOfHost)
hostString = String(string[startOfHost ..< endOfHost])
2018-10-19 14:03:17 +00:00
} else {
// Look for an IPv4-style endpoint, like 127.0.0.1:80
guard let endOfHost = string.firstIndex(of: ":") else { return nil }
startOfPort = string.index(after: endOfHost)
hostString = String(string[string.startIndex ..< endOfHost])
2018-10-19 14:03:17 +00:00
}
guard let endpointPort = NWEndpoint.Port(String(string[startOfPort ..< string.endIndex])) else { return nil }
let invalidCharacterIndex = hostString.unicodeScalars.firstIndex { char in
return !CharacterSet.urlHostAllowed.contains(char)
}
guard invalidCharacterIndex == nil else { return nil }
host = NWEndpoint.Host(hostString)
port = endpointPort
2018-10-19 14:03:17 +00:00
}
}
2018-11-06 18:06:48 +00:00
extension Endpoint {
func hasHostAsIPAddress() -> Bool {
switch host {
case .name:
2018-11-06 18:06:48 +00:00
return false
case .ipv4:
2018-11-06 18:06:48 +00:00
return true
case .ipv6:
2018-11-06 18:06:48 +00:00
return true
@unknown default:
fatalError()
2018-11-06 18:06:48 +00:00
}
}
2018-11-08 10:56:17 +00:00
func hostname() -> String? {
switch host {
2018-11-08 10:56:17 +00:00
case .name(let hostname, _):
return hostname
case .ipv4:
2018-11-08 10:56:17 +00:00
return nil
case .ipv6:
2018-11-08 10:56:17 +00:00
return nil
@unknown default:
fatalError()
2018-11-08 10:56:17 +00:00
}
}
2018-11-06 18:06:48 +00:00
}