Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 87f0526f09 | |||
| 060c027325 | |||
| 23bf3cfccb | |||
| 7f5ad3e503 | |||
| 820fa55380 | |||
| eb528c766b | |||
| 53235eb38f | |||
| b9ff5c2e94 | |||
| b7f69d20b6 | |||
| 6c4f4109eb | |||
| 7b5b564a6e | |||
| 695f868b1f | |||
| e724c043d9 | |||
| 491301f58b |
+1
-1
@@ -30,7 +30,7 @@ let package = Package(
|
|||||||
"goruntime-boottime-over-monotonic.diff",
|
"goruntime-boottime-over-monotonic.diff",
|
||||||
"go.mod",
|
"go.mod",
|
||||||
"go.sum",
|
"go.sum",
|
||||||
"api-ios.go",
|
"api-apple.go",
|
||||||
"Makefile"
|
"Makefile"
|
||||||
],
|
],
|
||||||
publicHeadersPath: ".",
|
publicHeadersPath: ".",
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ $ open WireGuard.xcodeproj
|
|||||||
the "External Build Tool Configuration":
|
the "External Build Tool Configuration":
|
||||||
|
|
||||||
```
|
```
|
||||||
$BUILD_DIR/../../SourcePackages/checkouts/wireguard-apple/Sources/WireGuardKitGo
|
${BUILD_DIR%Build/*}SourcePackages/checkouts/wireguard-apple/Sources/WireGuardKitGo
|
||||||
```
|
```
|
||||||
|
|
||||||
- Switch to "Build Settings" and find `SDKROOT`.
|
- Switch to "Build Settings" and find `SDKROOT`.
|
||||||
|
|||||||
@@ -109,6 +109,7 @@
|
|||||||
"tunnelOnDemandSectionTitleAddSSIDs" = "Add SSIDs";
|
"tunnelOnDemandSectionTitleAddSSIDs" = "Add SSIDs";
|
||||||
"tunnelOnDemandAddMessageAddConnectedSSID (%@)" = "Add connected: %@";
|
"tunnelOnDemandAddMessageAddConnectedSSID (%@)" = "Add connected: %@";
|
||||||
"tunnelOnDemandAddMessageAddNewSSID" = "Add new";
|
"tunnelOnDemandAddMessageAddNewSSID" = "Add new";
|
||||||
|
"tunnelOnDemandSSIDTextFieldPlaceholder" = "SSID";
|
||||||
|
|
||||||
"tunnelOnDemandKey" = "On demand";
|
"tunnelOnDemandKey" = "On demand";
|
||||||
"tunnelOnDemandOptionOff" = "Off";
|
"tunnelOnDemandOptionOff" = "Off";
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
VERSION_NAME = 1.0.12
|
VERSION_NAME = 1.0.13
|
||||||
VERSION_ID = 22
|
VERSION_ID = 24
|
||||||
|
|||||||
@@ -9,6 +9,11 @@ class EditableTextCell: UITableViewCell {
|
|||||||
set(value) { valueTextField.text = value }
|
set(value) { valueTextField.text = value }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var placeholder: String? {
|
||||||
|
get { return valueTextField.placeholder }
|
||||||
|
set(value) { valueTextField.placeholder = value }
|
||||||
|
}
|
||||||
|
|
||||||
let valueTextField: UITextField = {
|
let valueTextField: UITextField = {
|
||||||
let valueTextField = UITextField()
|
let valueTextField = UITextField()
|
||||||
valueTextField.textAlignment = .left
|
valueTextField.textAlignment = .left
|
||||||
@@ -29,12 +34,13 @@ class EditableTextCell: UITableViewCell {
|
|||||||
valueTextField.delegate = self
|
valueTextField.delegate = self
|
||||||
contentView.addSubview(valueTextField)
|
contentView.addSubview(valueTextField)
|
||||||
valueTextField.translatesAutoresizingMaskIntoConstraints = false
|
valueTextField.translatesAutoresizingMaskIntoConstraints = false
|
||||||
let bottomAnchorConstraint = contentView.layoutMarginsGuide.bottomAnchor.constraint(equalToSystemSpacingBelow: valueTextField.bottomAnchor, multiplier: 1)
|
// Reduce the bottom margin by 0.5pt to maintain the default cell height (44pt)
|
||||||
|
let bottomAnchorConstraint = contentView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: valueTextField.bottomAnchor, constant: -0.5)
|
||||||
bottomAnchorConstraint.priority = .defaultLow
|
bottomAnchorConstraint.priority = .defaultLow
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
valueTextField.leadingAnchor.constraint(equalToSystemSpacingAfter: contentView.layoutMarginsGuide.leadingAnchor, multiplier: 1),
|
valueTextField.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
|
||||||
contentView.layoutMarginsGuide.trailingAnchor.constraint(equalToSystemSpacingAfter: valueTextField.trailingAnchor, multiplier: 1),
|
contentView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: valueTextField.trailingAnchor),
|
||||||
valueTextField.topAnchor.constraint(equalToSystemSpacingBelow: contentView.layoutMarginsGuide.topAnchor, multiplier: 1),
|
contentView.layoutMarginsGuide.topAnchor.constraint(equalTo: valueTextField.topAnchor),
|
||||||
bottomAnchorConstraint
|
bottomAnchorConstraint
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
@@ -50,6 +56,7 @@ class EditableTextCell: UITableViewCell {
|
|||||||
override func prepareForReuse() {
|
override func prepareForReuse() {
|
||||||
super.prepareForReuse()
|
super.prepareForReuse()
|
||||||
message = ""
|
message = ""
|
||||||
|
placeholder = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class KeyValueCell: UITableViewCell {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
let valueTextField: UITextField = {
|
let valueTextField: UITextField = {
|
||||||
let valueTextField = UITextField()
|
let valueTextField = KeyValueCellTextField()
|
||||||
valueTextField.textAlignment = .right
|
valueTextField.textAlignment = .right
|
||||||
valueTextField.isEnabled = false
|
valueTextField.isEnabled = false
|
||||||
valueTextField.font = UIFont.preferredFont(forTextStyle: .body)
|
valueTextField.font = UIFont.preferredFont(forTextStyle: .body)
|
||||||
@@ -115,8 +115,6 @@ class KeyValueCell: UITableViewCell {
|
|||||||
expandToFitValueLabelConstraint.priority = .defaultLow + 1
|
expandToFitValueLabelConstraint.priority = .defaultLow + 1
|
||||||
expandToFitValueLabelConstraint.isActive = true
|
expandToFitValueLabelConstraint.isActive = true
|
||||||
|
|
||||||
contentView.addSubview(valueLabelScrollView)
|
|
||||||
|
|
||||||
contentView.addSubview(valueLabelScrollView)
|
contentView.addSubview(valueLabelScrollView)
|
||||||
valueLabelScrollView.translatesAutoresizingMaskIntoConstraints = false
|
valueLabelScrollView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
@@ -234,3 +232,10 @@ extension KeyValueCell: UITextFieldDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class KeyValueCellTextField: UITextField {
|
||||||
|
override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
|
||||||
|
// UIKit renders the placeholder label 0.5pt higher
|
||||||
|
return super.placeholderRect(forBounds: bounds).integral.offsetBy(dx: 0, dy: -0.5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+46
-22
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import SystemConfiguration.CaptiveNetwork
|
import SystemConfiguration.CaptiveNetwork
|
||||||
|
import NetworkExtension
|
||||||
|
|
||||||
protocol SSIDOptionEditTableViewControllerDelegate: class {
|
protocol SSIDOptionEditTableViewControllerDelegate: class {
|
||||||
func ssidOptionSaved(option: ActivateOnDemandViewModel.OnDemandSSIDOption, ssids: [String])
|
func ssidOptionSaved(option: ActivateOnDemandViewModel.OnDemandSSIDOption, ssids: [String])
|
||||||
@@ -39,9 +40,16 @@ class SSIDOptionEditTableViewController: UITableViewController {
|
|||||||
selectedOption = option
|
selectedOption = option
|
||||||
selectedSSIDs = ssids
|
selectedSSIDs = ssids
|
||||||
super.init(style: .grouped)
|
super.init(style: .grouped)
|
||||||
connectedSSID = getConnectedSSID()
|
|
||||||
loadSections()
|
loadSections()
|
||||||
loadAddSSIDRows()
|
addSSIDRows.removeAll()
|
||||||
|
addSSIDRows.append(.addNewSSID)
|
||||||
|
|
||||||
|
getConnectedSSID { [weak self] ssid in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.connectedSSID = ssid
|
||||||
|
self.updateCurrentSSIDEntry()
|
||||||
|
self.updateTableViewAddSSIDRows()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
required init?(coder aDecoder: NSCoder) {
|
||||||
@@ -60,6 +68,7 @@ class SSIDOptionEditTableViewController: UITableViewController {
|
|||||||
tableView.register(TextCell.self)
|
tableView.register(TextCell.self)
|
||||||
tableView.isEditing = true
|
tableView.isEditing = true
|
||||||
tableView.allowsSelectionDuringEditing = true
|
tableView.allowsSelectionDuringEditing = true
|
||||||
|
tableView.keyboardDismissMode = .onDrag
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadSections() {
|
func loadSections() {
|
||||||
@@ -71,14 +80,14 @@ class SSIDOptionEditTableViewController: UITableViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadAddSSIDRows() {
|
func updateCurrentSSIDEntry() {
|
||||||
addSSIDRows.removeAll()
|
if let connectedSSID = connectedSSID, !selectedSSIDs.contains(connectedSSID) {
|
||||||
if let connectedSSID = connectedSSID {
|
if let first = addSSIDRows.first, case .addNewSSID = first {
|
||||||
if !selectedSSIDs.contains(connectedSSID) {
|
addSSIDRows.insert(.addConnectedSSID(connectedSSID: connectedSSID), at: 0)
|
||||||
addSSIDRows.append(.addConnectedSSID(connectedSSID: connectedSSID))
|
|
||||||
}
|
}
|
||||||
|
} else if let first = addSSIDRows.first, case .addConnectedSSID = first {
|
||||||
|
addSSIDRows.removeFirst()
|
||||||
}
|
}
|
||||||
addSSIDRows.append(.addNewSSID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateTableViewAddSSIDRows() {
|
func updateTableViewAddSSIDRows() {
|
||||||
@@ -188,12 +197,13 @@ extension SSIDOptionEditTableViewController {
|
|||||||
private func selectedSSIDCell(for tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell {
|
private func selectedSSIDCell(for tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell {
|
||||||
let cell: EditableTextCell = tableView.dequeueReusableCell(for: indexPath)
|
let cell: EditableTextCell = tableView.dequeueReusableCell(for: indexPath)
|
||||||
cell.message = selectedSSIDs[indexPath.row]
|
cell.message = selectedSSIDs[indexPath.row]
|
||||||
|
cell.placeholder = tr("tunnelOnDemandSSIDTextFieldPlaceholder")
|
||||||
cell.isEditing = true
|
cell.isEditing = true
|
||||||
cell.onValueBeingEdited = { [weak self, weak cell] text in
|
cell.onValueBeingEdited = { [weak self, weak cell] text in
|
||||||
guard let self = self, let cell = cell else { return }
|
guard let self = self, let cell = cell else { return }
|
||||||
if let row = self.tableView.indexPath(for: cell)?.row {
|
if let row = self.tableView.indexPath(for: cell)?.row {
|
||||||
self.selectedSSIDs[row] = text
|
self.selectedSSIDs[row] = text
|
||||||
self.loadAddSSIDRows()
|
self.updateCurrentSSIDEntry()
|
||||||
self.updateTableViewAddSSIDRows()
|
self.updateTableViewAddSSIDRows()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,7 +234,7 @@ extension SSIDOptionEditTableViewController {
|
|||||||
} else {
|
} else {
|
||||||
tableView.reloadRows(at: [indexPath], with: .automatic)
|
tableView.reloadRows(at: [indexPath], with: .automatic)
|
||||||
}
|
}
|
||||||
loadAddSSIDRows()
|
updateCurrentSSIDEntry()
|
||||||
updateTableViewAddSSIDRows()
|
updateTableViewAddSSIDRows()
|
||||||
case .addSSIDs:
|
case .addSSIDs:
|
||||||
assert(editingStyle == .insert)
|
assert(editingStyle == .insert)
|
||||||
@@ -244,7 +254,7 @@ extension SSIDOptionEditTableViewController {
|
|||||||
} else {
|
} else {
|
||||||
tableView.insertRows(at: [indexPath], with: .automatic)
|
tableView.insertRows(at: [indexPath], with: .automatic)
|
||||||
}
|
}
|
||||||
loadAddSSIDRows()
|
updateCurrentSSIDEntry()
|
||||||
updateTableViewAddSSIDRows()
|
updateTableViewAddSSIDRows()
|
||||||
if newSSID.isEmpty {
|
if newSSID.isEmpty {
|
||||||
if let selectedSSIDCell = tableView.cellForRow(at: indexPath) as? EditableTextCell {
|
if let selectedSSIDCell = tableView.cellForRow(at: indexPath) as? EditableTextCell {
|
||||||
@@ -253,6 +263,31 @@ extension SSIDOptionEditTableViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func getConnectedSSID(completionHandler: @escaping (String?) -> Void) {
|
||||||
|
#if targetEnvironment(simulator)
|
||||||
|
completionHandler("Simulator Wi-Fi")
|
||||||
|
#else
|
||||||
|
if #available(iOS 14, *) {
|
||||||
|
NEHotspotNetwork.fetchCurrent { hotspotNetwork in
|
||||||
|
completionHandler(hotspotNetwork?.ssid)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let supportedInterfaces = CNCopySupportedInterfaces() as? [CFString] {
|
||||||
|
for interface in supportedInterfaces {
|
||||||
|
if let networkInfo = CNCopyCurrentNetworkInfo(interface) {
|
||||||
|
if let ssid = (networkInfo as NSDictionary)[kCNNetworkInfoKeySSID as String] as? String {
|
||||||
|
completionHandler(!ssid.isEmpty ? ssid : nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
completionHandler(nil)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SSIDOptionEditTableViewController {
|
extension SSIDOptionEditTableViewController {
|
||||||
@@ -290,14 +325,3 @@ extension SSIDOptionEditTableViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getConnectedSSID() -> String? {
|
|
||||||
guard let supportedInterfaces = CNCopySupportedInterfaces() as? [CFString] else { return nil }
|
|
||||||
for interface in supportedInterfaces {
|
|
||||||
if let networkInfo = CNCopyCurrentNetworkInfo(interface) {
|
|
||||||
if let ssid = (networkInfo as NSDictionary)[kCNNetworkInfoKeySSID as String] as? String {
|
|
||||||
return !ssid.isEmpty ? ssid : nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -395,6 +395,7 @@ extension TunnelDetailTableViewController {
|
|||||||
let cell: KeyValueCell = tableView.dequeueReusableCell(for: indexPath)
|
let cell: KeyValueCell = tableView.dequeueReusableCell(for: indexPath)
|
||||||
cell.key = field.localizedUIString
|
cell.key = field.localizedUIString
|
||||||
cell.value = onDemandViewModel.localizedInterfaceDescription
|
cell.value = onDemandViewModel.localizedInterfaceDescription
|
||||||
|
cell.copyableGesture = false
|
||||||
return cell
|
return cell
|
||||||
} else {
|
} else {
|
||||||
assert(field == .ssid)
|
assert(field == .ssid)
|
||||||
@@ -402,6 +403,7 @@ extension TunnelDetailTableViewController {
|
|||||||
let cell: KeyValueCell = tableView.dequeueReusableCell(for: indexPath)
|
let cell: KeyValueCell = tableView.dequeueReusableCell(for: indexPath)
|
||||||
cell.key = field.localizedUIString
|
cell.key = field.localizedUIString
|
||||||
cell.value = onDemandViewModel.ssidOption.localizedUIString
|
cell.value = onDemandViewModel.ssidOption.localizedUIString
|
||||||
|
cell.copyableGesture = false
|
||||||
return cell
|
return cell
|
||||||
} else {
|
} else {
|
||||||
let cell: ChevronCell = tableView.dequeueReusableCell(for: indexPath)
|
let cell: ChevronCell = tableView.dequeueReusableCell(for: indexPath)
|
||||||
|
|||||||
@@ -64,4 +64,52 @@ extension IPAddressRange {
|
|||||||
|
|
||||||
return (address, networkPrefixLength)
|
return (address, networkPrefixLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func subnetMask() -> IPAddress {
|
||||||
|
if address is IPv4Address {
|
||||||
|
let mask = networkPrefixLength > 0 ? ~UInt32(0) << (32 - networkPrefixLength) : UInt32(0)
|
||||||
|
let bytes = Data([
|
||||||
|
UInt8(truncatingIfNeeded: mask >> 24),
|
||||||
|
UInt8(truncatingIfNeeded: mask >> 16),
|
||||||
|
UInt8(truncatingIfNeeded: mask >> 8),
|
||||||
|
UInt8(truncatingIfNeeded: mask >> 0)
|
||||||
|
])
|
||||||
|
return IPv4Address(bytes)!
|
||||||
|
}
|
||||||
|
if address is IPv6Address {
|
||||||
|
var bytes = Data(repeating: 0, count: 16)
|
||||||
|
for i in 0..<Int(networkPrefixLength/8) {
|
||||||
|
bytes[i] = 0xff
|
||||||
|
}
|
||||||
|
let nibble = networkPrefixLength % 32
|
||||||
|
if nibble != 0 {
|
||||||
|
let mask = ~UInt32(0) << (32 - nibble)
|
||||||
|
let i = Int(networkPrefixLength / 32 * 4)
|
||||||
|
bytes[i + 0] = UInt8(truncatingIfNeeded: mask >> 24)
|
||||||
|
bytes[i + 1] = UInt8(truncatingIfNeeded: mask >> 16)
|
||||||
|
bytes[i + 2] = UInt8(truncatingIfNeeded: mask >> 8)
|
||||||
|
bytes[i + 3] = UInt8(truncatingIfNeeded: mask >> 0)
|
||||||
|
}
|
||||||
|
return IPv6Address(bytes)!
|
||||||
|
}
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func maskedAddress() -> IPAddress {
|
||||||
|
let subnet = subnetMask().rawValue
|
||||||
|
var masked = Data(address.rawValue)
|
||||||
|
if subnet.count != masked.count {
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
for i in 0..<subnet.count {
|
||||||
|
masked[i] &= subnet[i]
|
||||||
|
}
|
||||||
|
if subnet.count == 4 {
|
||||||
|
return IPv4Address(masked)!
|
||||||
|
}
|
||||||
|
if subnet.count == 16 {
|
||||||
|
return IPv6Address(masked)!
|
||||||
|
}
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,38 +113,26 @@ class PacketTunnelSettingsGenerator {
|
|||||||
networkSettings.mtu = NSNumber(value: mtu)
|
networkSettings.mtu = NSNumber(value: mtu)
|
||||||
}
|
}
|
||||||
|
|
||||||
let (ipv4Routes, ipv6Routes) = routes()
|
let (ipv4Addresses, ipv6Addresses) = addresses()
|
||||||
let (ipv4IncludedRoutes, ipv6IncludedRoutes) = includedRoutes()
|
let (ipv4IncludedRoutes, ipv6IncludedRoutes) = includedRoutes()
|
||||||
|
|
||||||
let ipv4Settings = NEIPv4Settings(addresses: ipv4Routes.map { $0.destinationAddress }, subnetMasks: ipv4Routes.map { $0.destinationSubnetMask })
|
let ipv4Settings = NEIPv4Settings(addresses: ipv4Addresses.map { $0.destinationAddress }, subnetMasks: ipv4Addresses.map { $0.destinationSubnetMask })
|
||||||
ipv4Settings.includedRoutes = ipv4IncludedRoutes
|
ipv4Settings.includedRoutes = ipv4IncludedRoutes
|
||||||
networkSettings.ipv4Settings = ipv4Settings
|
networkSettings.ipv4Settings = ipv4Settings
|
||||||
|
|
||||||
let ipv6Settings = NEIPv6Settings(addresses: ipv6Routes.map { $0.destinationAddress }, networkPrefixLengths: ipv6Routes.map { $0.destinationNetworkPrefixLength })
|
let ipv6Settings = NEIPv6Settings(addresses: ipv6Addresses.map { $0.destinationAddress }, networkPrefixLengths: ipv6Addresses.map { $0.destinationNetworkPrefixLength })
|
||||||
ipv6Settings.includedRoutes = ipv6IncludedRoutes
|
ipv6Settings.includedRoutes = ipv6IncludedRoutes
|
||||||
networkSettings.ipv6Settings = ipv6Settings
|
networkSettings.ipv6Settings = ipv6Settings
|
||||||
|
|
||||||
return networkSettings
|
return networkSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
private func ipv4SubnetMaskString(of addressRange: IPAddressRange) -> String {
|
private func addresses() -> ([NEIPv4Route], [NEIPv6Route]) {
|
||||||
let length: UInt8 = addressRange.networkPrefixLength
|
|
||||||
assert(length <= 32)
|
|
||||||
var octets: [UInt8] = [0, 0, 0, 0]
|
|
||||||
let subnetMask: UInt32 = length > 0 ? ~UInt32(0) << (32 - length) : UInt32(0)
|
|
||||||
octets[0] = UInt8(truncatingIfNeeded: subnetMask >> 24)
|
|
||||||
octets[1] = UInt8(truncatingIfNeeded: subnetMask >> 16)
|
|
||||||
octets[2] = UInt8(truncatingIfNeeded: subnetMask >> 8)
|
|
||||||
octets[3] = UInt8(truncatingIfNeeded: subnetMask)
|
|
||||||
return octets.map { String($0) }.joined(separator: ".")
|
|
||||||
}
|
|
||||||
|
|
||||||
private func routes() -> ([NEIPv4Route], [NEIPv6Route]) {
|
|
||||||
var ipv4Routes = [NEIPv4Route]()
|
var ipv4Routes = [NEIPv4Route]()
|
||||||
var ipv6Routes = [NEIPv6Route]()
|
var ipv6Routes = [NEIPv6Route]()
|
||||||
for addressRange in tunnelConfiguration.interface.addresses {
|
for addressRange in tunnelConfiguration.interface.addresses {
|
||||||
if addressRange.address is IPv4Address {
|
if addressRange.address is IPv4Address {
|
||||||
ipv4Routes.append(NEIPv4Route(destinationAddress: "\(addressRange.address)", subnetMask: ipv4SubnetMaskString(of: addressRange)))
|
ipv4Routes.append(NEIPv4Route(destinationAddress: "\(addressRange.address)", subnetMask: "\(addressRange.subnetMask())"))
|
||||||
} else if addressRange.address is IPv6Address {
|
} else if addressRange.address is IPv6Address {
|
||||||
/* Big fat ugly hack for broken iOS networking stack: the smallest prefix that will have
|
/* Big fat ugly hack for broken iOS networking stack: the smallest prefix that will have
|
||||||
* any effect on iOS is a /120, so we clamp everything above to /120. This is potentially
|
* any effect on iOS is a /120, so we clamp everything above to /120. This is potentially
|
||||||
@@ -160,10 +148,23 @@ class PacketTunnelSettingsGenerator {
|
|||||||
private func includedRoutes() -> ([NEIPv4Route], [NEIPv6Route]) {
|
private func includedRoutes() -> ([NEIPv4Route], [NEIPv6Route]) {
|
||||||
var ipv4IncludedRoutes = [NEIPv4Route]()
|
var ipv4IncludedRoutes = [NEIPv4Route]()
|
||||||
var ipv6IncludedRoutes = [NEIPv6Route]()
|
var ipv6IncludedRoutes = [NEIPv6Route]()
|
||||||
|
|
||||||
|
for addressRange in tunnelConfiguration.interface.addresses {
|
||||||
|
if addressRange.address is IPv4Address {
|
||||||
|
let route = NEIPv4Route(destinationAddress: "\(addressRange.maskedAddress())", subnetMask: "\(addressRange.subnetMask())")
|
||||||
|
route.gatewayAddress = "\(addressRange.address)"
|
||||||
|
ipv4IncludedRoutes.append(route)
|
||||||
|
} else if addressRange.address is IPv6Address {
|
||||||
|
let route = NEIPv6Route(destinationAddress: "\(addressRange.maskedAddress())", networkPrefixLength: NSNumber(value: addressRange.networkPrefixLength))
|
||||||
|
route.gatewayAddress = "\(addressRange.address)"
|
||||||
|
ipv6IncludedRoutes.append(route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for peer in tunnelConfiguration.peers {
|
for peer in tunnelConfiguration.peers {
|
||||||
for addressRange in peer.allowedIPs {
|
for addressRange in peer.allowedIPs {
|
||||||
if addressRange.address is IPv4Address {
|
if addressRange.address is IPv4Address {
|
||||||
ipv4IncludedRoutes.append(NEIPv4Route(destinationAddress: "\(addressRange.address)", subnetMask: ipv4SubnetMaskString(of: addressRange)))
|
ipv4IncludedRoutes.append(NEIPv4Route(destinationAddress: "\(addressRange.address)", subnetMask: "\(addressRange.subnetMask())"))
|
||||||
} else if addressRange.address is IPv6Address {
|
} else if addressRange.address is IPv6Address {
|
||||||
ipv6IncludedRoutes.append(NEIPv6Route(destinationAddress: "\(addressRange.address)", networkPrefixLength: NSNumber(value: addressRange.networkPrefixLength)))
|
ipv6IncludedRoutes.append(NEIPv6Route(destinationAddress: "\(addressRange.address)", networkPrefixLength: NSNumber(value: addressRange.networkPrefixLength)))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,12 +57,43 @@ public class WireGuardAdapter {
|
|||||||
|
|
||||||
/// Tunnel device file descriptor.
|
/// Tunnel device file descriptor.
|
||||||
private var tunnelFileDescriptor: Int32? {
|
private var tunnelFileDescriptor: Int32? {
|
||||||
return self.packetTunnelProvider?.packetFlow.value(forKeyPath: "socket.fileDescriptor") as? Int32
|
var ctlInfo = ctl_info()
|
||||||
|
withUnsafeMutablePointer(to: &ctlInfo.ctl_name) {
|
||||||
|
$0.withMemoryRebound(to: CChar.self, capacity: MemoryLayout.size(ofValue: $0.pointee)) {
|
||||||
|
_ = strcpy($0, "com.apple.net.utun_control")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for fd: Int32 in 0...1024 {
|
||||||
|
var addr = sockaddr_ctl()
|
||||||
|
var ret: Int32 = -1
|
||||||
|
var len = socklen_t(MemoryLayout.size(ofValue: addr))
|
||||||
|
withUnsafeMutablePointer(to: &addr) {
|
||||||
|
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
|
||||||
|
ret = getpeername(fd, $0, &len)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ret != 0 || addr.sc_family != AF_SYSTEM {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ctlInfo.ctl_id == 0 {
|
||||||
|
ret = ioctl(fd, CTLIOCGINFO, &ctlInfo)
|
||||||
|
if ret != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if addr.sc_id == ctlInfo.ctl_id {
|
||||||
|
return fd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a WireGuard version.
|
/// Returns a WireGuard version.
|
||||||
class var backendVersion: String {
|
class var backendVersion: String {
|
||||||
return String(cString: wgVersion())
|
guard let ver = wgVersion() else { return "unknown" }
|
||||||
|
let str = String(cString: ver)
|
||||||
|
free(UnsafeMutableRawPointer(mutating: ver))
|
||||||
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the tunnel device interface name, or nil on error.
|
/// Returns the tunnel device interface name, or nil on error.
|
||||||
@@ -265,7 +296,7 @@ public class WireGuardAdapter {
|
|||||||
.takeUnretainedValue()
|
.takeUnretainedValue()
|
||||||
|
|
||||||
let swiftString = String(cString: message).trimmingCharacters(in: .newlines)
|
let swiftString = String(cString: message).trimmingCharacters(in: .newlines)
|
||||||
let tunnelLogLevel = WireGuardLogLevel(rawValue: logLevel) ?? .debug
|
let tunnelLogLevel = WireGuardLogLevel(rawValue: logLevel) ?? .verbose
|
||||||
|
|
||||||
unretainedSelf.logHandler(tunnelLogLevel, swiftString)
|
unretainedSelf.logHandler(tunnelLogLevel, swiftString)
|
||||||
}
|
}
|
||||||
@@ -369,9 +400,9 @@ public class WireGuardAdapter {
|
|||||||
switch result {
|
switch result {
|
||||||
case .success((let sourceEndpoint, let resolvedEndpoint)):
|
case .success((let sourceEndpoint, let resolvedEndpoint)):
|
||||||
if sourceEndpoint.host == resolvedEndpoint.host {
|
if sourceEndpoint.host == resolvedEndpoint.host {
|
||||||
self.logHandler(.debug, "DNS64: mapped \(sourceEndpoint.host) to itself.")
|
self.logHandler(.verbose, "DNS64: mapped \(sourceEndpoint.host) to itself.")
|
||||||
} else {
|
} else {
|
||||||
self.logHandler(.debug, "DNS64: mapped \(sourceEndpoint.host) to \(resolvedEndpoint.host)")
|
self.logHandler(.verbose, "DNS64: mapped \(sourceEndpoint.host) to \(resolvedEndpoint.host)")
|
||||||
}
|
}
|
||||||
case .failure(let resolutionError):
|
case .failure(let resolutionError):
|
||||||
self.logHandler(.error, "Failed to resolve endpoint \(resolutionError.address): \(resolutionError.errorDescription ?? "(nil)")")
|
self.logHandler(.error, "Failed to resolve endpoint \(resolutionError.address): \(resolutionError.errorDescription ?? "(nil)")")
|
||||||
@@ -382,7 +413,7 @@ public class WireGuardAdapter {
|
|||||||
/// Helper method used by network path monitor.
|
/// Helper method used by network path monitor.
|
||||||
/// - Parameter path: new network path
|
/// - Parameter path: new network path
|
||||||
private func didReceivePathUpdate(path: Network.NWPath) {
|
private func didReceivePathUpdate(path: Network.NWPath) {
|
||||||
self.logHandler(.debug, "Network change detected with \(path.status) route and interface order \(path.availableInterfaces)")
|
self.logHandler(.verbose, "Network change detected with \(path.status) route and interface order \(path.availableInterfaces)")
|
||||||
|
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
if case .started(let handle, _) = self.state {
|
if case .started(let handle, _) = self.state {
|
||||||
@@ -399,7 +430,7 @@ public class WireGuardAdapter {
|
|||||||
wgDisableSomeRoamingForBrokenMobileSemantics(handle)
|
wgDisableSomeRoamingForBrokenMobileSemantics(handle)
|
||||||
wgBumpSockets(handle)
|
wgBumpSockets(handle)
|
||||||
} else {
|
} else {
|
||||||
self.logHandler(.info, "Connectivity offline, pausing backend.")
|
self.logHandler(.verbose, "Connectivity offline, pausing backend.")
|
||||||
|
|
||||||
self.state = .temporaryShutdown(settingsGenerator)
|
self.state = .temporaryShutdown(settingsGenerator)
|
||||||
wgTurnOff(handle)
|
wgTurnOff(handle)
|
||||||
@@ -408,7 +439,7 @@ public class WireGuardAdapter {
|
|||||||
case .temporaryShutdown(let settingsGenerator):
|
case .temporaryShutdown(let settingsGenerator):
|
||||||
guard path.status.isSatisfiable else { return }
|
guard path.status.isSatisfiable else { return }
|
||||||
|
|
||||||
self.logHandler(.info, "Connectivity online, resuming backend.")
|
self.logHandler(.verbose, "Connectivity online, resuming backend.")
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try self.setNetworkSettings(settingsGenerator.generateNetworkSettings())
|
try self.setNetworkSettings(settingsGenerator.generateNetworkSettings())
|
||||||
@@ -434,11 +465,10 @@ public class WireGuardAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A enum describing WireGuard log levels defined in `api-ios.go`.
|
/// A enum describing WireGuard log levels defined in `api-apple.go`.
|
||||||
public enum WireGuardLogLevel: Int32 {
|
public enum WireGuardLogLevel: Int32 {
|
||||||
case debug = 0
|
case verbose = 0
|
||||||
case info = 1
|
case error = 1
|
||||||
case error = 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension Network.NWPath.Status {
|
private extension Network.NWPath.Status {
|
||||||
|
|||||||
@@ -3,3 +3,18 @@
|
|||||||
|
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "x25519.h"
|
#include "x25519.h"
|
||||||
|
|
||||||
|
/* From <sys/kern_control.h> */
|
||||||
|
#define CTLIOCGINFO 0xc0644e03UL
|
||||||
|
struct ctl_info {
|
||||||
|
u_int32_t ctl_id;
|
||||||
|
char ctl_name[96];
|
||||||
|
};
|
||||||
|
struct sockaddr_ctl {
|
||||||
|
u_char sc_len;
|
||||||
|
u_char sc_family;
|
||||||
|
u_int16_t ss_sysaddr;
|
||||||
|
u_int32_t sc_id;
|
||||||
|
u_int32_t sc_unit;
|
||||||
|
u_int32_t sc_reserved[5];
|
||||||
|
};
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
# Copyright (C) 2018-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
# Copyright (C) 2018-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||||
|
|
||||||
# These are generally passed to us by xcode, but we set working defaults for standalone compilation too.
|
# These are generally passed to us by xcode, but we set working defaults for standalone compilation too.
|
||||||
ARCHS ?= x86_64 #TODO: add arm64 to this list once we support apple silicon
|
ARCHS ?= x86_64 arm64
|
||||||
SDK_NAME ?= macosx
|
PLATFORM_NAME ?= macosx
|
||||||
SDKROOT ?= $(shell xcrun --sdk $(SDK_NAME) --show-sdk-path)
|
SDKROOT ?= $(shell xcrun --sdk $(PLATFORM_NAME) --show-sdk-path)
|
||||||
CONFIGURATION_BUILD_DIR ?= $(CURDIR)/out
|
CONFIGURATION_BUILD_DIR ?= $(CURDIR)/out
|
||||||
CONFIGURATION_TEMP_DIR ?= $(CURDIR)/.tmp
|
CONFIGURATION_TEMP_DIR ?= $(CURDIR)/.tmp
|
||||||
|
|
||||||
@@ -17,6 +17,8 @@ BUILDDIR ?= $(CONFIGURATION_TEMP_DIR)/wireguard-go-bridge
|
|||||||
CFLAGS_PREFIX := $(if $(DEPLOYMENT_TARGET_CLANG_FLAG_NAME),-$(DEPLOYMENT_TARGET_CLANG_FLAG_NAME)=$($(DEPLOYMENT_TARGET_CLANG_ENV_NAME)),) -isysroot $(SDKROOT) -arch
|
CFLAGS_PREFIX := $(if $(DEPLOYMENT_TARGET_CLANG_FLAG_NAME),-$(DEPLOYMENT_TARGET_CLANG_FLAG_NAME)=$($(DEPLOYMENT_TARGET_CLANG_ENV_NAME)),) -isysroot $(SDKROOT) -arch
|
||||||
GOARCH_arm64 := arm64
|
GOARCH_arm64 := arm64
|
||||||
GOARCH_x86_64 := amd64
|
GOARCH_x86_64 := amd64
|
||||||
|
GOOS_macosx := darwin
|
||||||
|
GOOS_iphoneos := ios
|
||||||
|
|
||||||
build: $(DESTDIR)/libwg-go.a
|
build: $(DESTDIR)/libwg-go.a
|
||||||
version-header: $(DESTDIR)/wireguard-go-version.h
|
version-header: $(DESTDIR)/wireguard-go-version.h
|
||||||
@@ -34,16 +36,16 @@ define libwg-go-a
|
|||||||
$(BUILDDIR)/libwg-go-$(1).a: export CGO_ENABLED := 1
|
$(BUILDDIR)/libwg-go-$(1).a: export CGO_ENABLED := 1
|
||||||
$(BUILDDIR)/libwg-go-$(1).a: export CGO_CFLAGS := $(CFLAGS_PREFIX) $(ARCH)
|
$(BUILDDIR)/libwg-go-$(1).a: export CGO_CFLAGS := $(CFLAGS_PREFIX) $(ARCH)
|
||||||
$(BUILDDIR)/libwg-go-$(1).a: export CGO_LDFLAGS := $(CFLAGS_PREFIX) $(ARCH)
|
$(BUILDDIR)/libwg-go-$(1).a: export CGO_LDFLAGS := $(CFLAGS_PREFIX) $(ARCH)
|
||||||
$(BUILDDIR)/libwg-go-$(1).a: export GOOS := darwin
|
$(BUILDDIR)/libwg-go-$(1).a: export GOOS := $(GOOS_$(PLATFORM_NAME))
|
||||||
$(BUILDDIR)/libwg-go-$(1).a: export GOARCH := $(GOARCH_$(1))
|
$(BUILDDIR)/libwg-go-$(1).a: export GOARCH := $(GOARCH_$(1))
|
||||||
$(BUILDDIR)/libwg-go-$(1).a: $(GOROOT)/.prepared go.mod
|
$(BUILDDIR)/libwg-go-$(1).a: $(GOROOT)/.prepared go.mod
|
||||||
go build -tags ios -ldflags=-w -trimpath -v -o "$(BUILDDIR)/libwg-go-$(1).a" -buildmode c-archive
|
go build -ldflags=-w -trimpath -v -o "$(BUILDDIR)/libwg-go-$(1).a" -buildmode c-archive
|
||||||
rm -f "$(BUILDDIR)/libwg-go-$(1).h"
|
rm -f "$(BUILDDIR)/libwg-go-$(1).h"
|
||||||
endef
|
endef
|
||||||
$(foreach ARCH,$(ARCHS),$(eval $(call libwg-go-a,$(ARCH))))
|
$(foreach ARCH,$(ARCHS),$(eval $(call libwg-go-a,$(ARCH))))
|
||||||
|
|
||||||
$(DESTDIR)/wireguard-go-version.h: $(GOROOT)/.prepared go.mod
|
$(DESTDIR)/wireguard-go-version.h: go.mod $(GOROOT)/.prepared
|
||||||
go list -m golang.zx2c4.com/wireguard | sed -n 's/.*v\([0-9.]*\).*/#define WIREGUARD_GO_VERSION "\1"/p' > "$@"
|
sed -E -n 's/.*golang\.zx2c4\.com\/wireguard +v[0-9.]+-[0-9]+-([0-9a-f]{8})[0-9a-f]{4}.*/#define WIREGUARD_GO_VERSION "\1"/p' "$<" > "$@"
|
||||||
|
|
||||||
$(DESTDIR)/libwg-go.a: $(foreach ARCH,$(ARCHS),$(BUILDDIR)/libwg-go-$(ARCH).a)
|
$(DESTDIR)/libwg-go.a: $(foreach ARCH,$(ARCHS),$(BUILDDIR)/libwg-go-$(ARCH).a)
|
||||||
@mkdir -vp "$(DESTDIR)"
|
@mkdir -vp "$(DESTDIR)"
|
||||||
|
|||||||
@@ -14,36 +14,41 @@ package main
|
|||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"fmt"
|
||||||
"log"
|
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"runtime/debug"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
"golang.zx2c4.com/wireguard/conn"
|
||||||
"golang.zx2c4.com/wireguard/device"
|
"golang.zx2c4.com/wireguard/device"
|
||||||
"golang.zx2c4.com/wireguard/tun"
|
"golang.zx2c4.com/wireguard/tun"
|
||||||
)
|
)
|
||||||
|
|
||||||
var loggerFunc unsafe.Pointer
|
var loggerFunc unsafe.Pointer
|
||||||
var loggerCtx unsafe.Pointer
|
var loggerCtx unsafe.Pointer
|
||||||
var versionString *C.char
|
|
||||||
|
|
||||||
type CLogger struct {
|
type CLogger int
|
||||||
level C.int
|
|
||||||
|
func cstring(s string) *C.char {
|
||||||
|
b, err := unix.BytePtrFromString(s)
|
||||||
|
if err != nil {
|
||||||
|
b := [1]C.char{}
|
||||||
|
return &b[0]
|
||||||
|
}
|
||||||
|
return (*C.char)(unsafe.Pointer(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *CLogger) Write(p []byte) (int, error) {
|
func (l CLogger) Printf(format string, args ...interface{}) {
|
||||||
if uintptr(loggerFunc) == 0 {
|
if uintptr(loggerFunc) == 0 {
|
||||||
return 0, errors.New("No logger initialized")
|
return
|
||||||
}
|
}
|
||||||
message := C.CString(string(p))
|
C.callLogger(loggerFunc, loggerCtx, C.int(l), cstring(fmt.Sprintf(format, args...)))
|
||||||
C.callLogger(loggerFunc, loggerCtx, l.level, message)
|
|
||||||
C.free(unsafe.Pointer(message))
|
|
||||||
return len(p), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type tunnelHandle struct {
|
type tunnelHandle struct {
|
||||||
@@ -54,7 +59,6 @@ type tunnelHandle struct {
|
|||||||
var tunnelHandles = make(map[int32]tunnelHandle)
|
var tunnelHandles = make(map[int32]tunnelHandle)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
versionString = C.CString(device.WireGuardGoVersion)
|
|
||||||
signals := make(chan os.Signal)
|
signals := make(chan os.Signal)
|
||||||
signal.Notify(signals, unix.SIGUSR2)
|
signal.Notify(signals, unix.SIGUSR2)
|
||||||
go func() {
|
go func() {
|
||||||
@@ -81,40 +85,39 @@ func wgSetLogger(context, loggerFn uintptr) {
|
|||||||
//export wgTurnOn
|
//export wgTurnOn
|
||||||
func wgTurnOn(settings *C.char, tunFd int32) int32 {
|
func wgTurnOn(settings *C.char, tunFd int32) int32 {
|
||||||
logger := &device.Logger{
|
logger := &device.Logger{
|
||||||
Debug: log.New(&CLogger{level: 0}, "", 0),
|
Verbosef: CLogger(0).Printf,
|
||||||
Info: log.New(&CLogger{level: 1}, "", 0),
|
Errorf: CLogger(1).Printf,
|
||||||
Error: log.New(&CLogger{level: 2}, "", 0),
|
|
||||||
}
|
}
|
||||||
dupTunFd, err := unix.Dup(int(tunFd))
|
dupTunFd, err := unix.Dup(int(tunFd))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Println(err)
|
logger.Errorf("Unable to dup tun fd: %v", err)
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
err = unix.SetNonblock(dupTunFd, true)
|
err = unix.SetNonblock(dupTunFd, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Println(err)
|
logger.Errorf("Unable to set tun fd as non blocking: %v", err)
|
||||||
unix.Close(dupTunFd)
|
unix.Close(dupTunFd)
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
tun, err := tun.CreateTUNFromFile(os.NewFile(uintptr(dupTunFd), "/dev/tun"), 0)
|
tun, err := tun.CreateTUNFromFile(os.NewFile(uintptr(dupTunFd), "/dev/tun"), 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Println(err)
|
logger.Errorf("Unable to create new tun device from fd: %v", err)
|
||||||
unix.Close(dupTunFd)
|
unix.Close(dupTunFd)
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
logger.Info.Println("Attaching to interface")
|
logger.Verbosef("Attaching to interface")
|
||||||
dev := device.NewDevice(tun, logger)
|
dev := device.NewDevice(tun, conn.NewStdNetBind(), logger)
|
||||||
|
|
||||||
err = dev.IpcSet(C.GoString(settings))
|
err = dev.IpcSet(C.GoString(settings))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Println(err)
|
logger.Errorf("Unable to set IPC settings: %v", err)
|
||||||
unix.Close(dupTunFd)
|
unix.Close(dupTunFd)
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
dev.Up()
|
dev.Up()
|
||||||
logger.Info.Println("Device started")
|
logger.Verbosef("Device started")
|
||||||
|
|
||||||
var i int32
|
var i int32
|
||||||
for i = 0; i < math.MaxInt32; i++ {
|
for i = 0; i < math.MaxInt32; i++ {
|
||||||
@@ -148,7 +151,7 @@ func wgSetConfig(tunnelHandle int32, settings *C.char) int64 {
|
|||||||
}
|
}
|
||||||
err := dev.IpcSet(C.GoString(settings))
|
err := dev.IpcSet(C.GoString(settings))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dev.Error.Println(err)
|
dev.Errorf("Unable to set IPC settings: %v", err)
|
||||||
if ipcErr, ok := err.(*device.IPCError); ok {
|
if ipcErr, ok := err.(*device.IPCError); ok {
|
||||||
return ipcErr.ErrorCode()
|
return ipcErr.ErrorCode()
|
||||||
}
|
}
|
||||||
@@ -183,10 +186,10 @@ func wgBumpSockets(tunnelHandle int32) {
|
|||||||
dev.SendKeepalivesToPeersWithCurrentKeypair()
|
dev.SendKeepalivesToPeersWithCurrentKeypair()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dev.Error.Printf("Unable to update bind, try %d: %v", i+1, err)
|
dev.Errorf("Unable to update bind, try %d: %v", i+1, err)
|
||||||
time.Sleep(time.Second / 2)
|
time.Sleep(time.Second / 2)
|
||||||
}
|
}
|
||||||
dev.Error.Println("Gave up trying to update bind; tunnel is likely dysfunctional")
|
dev.Errorf("Gave up trying to update bind; tunnel is likely dysfunctional")
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,7 +204,20 @@ func wgDisableSomeRoamingForBrokenMobileSemantics(tunnelHandle int32) {
|
|||||||
|
|
||||||
//export wgVersion
|
//export wgVersion
|
||||||
func wgVersion() *C.char {
|
func wgVersion() *C.char {
|
||||||
return versionString
|
info, ok := debug.ReadBuildInfo()
|
||||||
|
if !ok {
|
||||||
|
return C.CString("unknown")
|
||||||
|
}
|
||||||
|
for _, dep := range info.Deps {
|
||||||
|
if dep.Path == "golang.zx2c4.com/wireguard" {
|
||||||
|
parts := strings.Split(dep.Version, "-")
|
||||||
|
if len(parts) == 3 && len(parts[2]) == 12 {
|
||||||
|
return C.CString(parts[2][:7])
|
||||||
|
}
|
||||||
|
return C.CString(dep.Version)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return C.CString("unknown")
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {}
|
func main() {}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
module golang.zx2c4.com/wireguard/ios
|
module golang.zx2c4.com/wireguard/apple
|
||||||
|
|
||||||
go 1.15
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
|
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
|
||||||
golang.org/x/net v0.0.0-20201216054612-986b41b23924 // indirect
|
golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect
|
||||||
golang.org/x/sys v0.0.0-20201223074533-0d417f636930
|
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22
|
||||||
golang.zx2c4.com/wireguard v0.0.20201119-0.20201223104851-e467e07bbf51
|
golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,24 +1,23 @@
|
|||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
|
||||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
|
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20201216054612-986b41b23924 h1:QsnDpLLOKwHBBDa8nDws4DYNc/ryVW2vCpxCs09d4PY=
|
golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
|
||||||
golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201223074533-0d417f636930 h1:vRgIt+nup/B/BwIS0g2oC0haq0iqbV3ZA+u6+0TlNCo=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201223074533-0d417f636930/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio=
|
||||||
|
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.zx2c4.com/wireguard v0.0.20201119-0.20201223104851-e467e07bbf51 h1:F62E0jQdNkXUnELQw+NaOnMxdEnnGScuywq0NdB4YTQ=
|
golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2 h1:wfOOSvHgIzTZ9h5Vb6yUFZNn7uf3bT7PeYsHOO7tYDM=
|
||||||
golang.zx2c4.com/wireguard v0.0.20201119-0.20201223104851-e467e07bbf51/go.mod h1:ITsWNpkFv78VPB7f8MiyuxeEMcHR4jfxHGCJLPP3GHs=
|
golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2/go.mod h1:laHzsbfMhGSobUmruXWAyMKKHSqvIcrqZJMyHD+/3O8=
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
From aa85e0f90c9031ff5be32296e9fed1637a2eceae Mon Sep 17 00:00:00 2001
|
From 516dc0c15ff1ab781e0677606b5be72919251b3e Mon Sep 17 00:00:00 2001
|
||||||
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
||||||
Date: Wed, 9 Dec 2020 14:07:06 +0100
|
Date: Wed, 9 Dec 2020 14:07:06 +0100
|
||||||
Subject: [PATCH] runtime: use libc_mach_continuous_time in nanotime on Darwin
|
Subject: [PATCH] runtime: use libc_mach_continuous_time in nanotime on Darwin
|
||||||
@@ -18,23 +18,23 @@ Change-Id: Ia3282e8bd86f95ad2b76427063e60a005563f4eb
|
|||||||
3 files changed, 3 insertions(+), 3 deletions(-)
|
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
diff --git a/src/runtime/sys_darwin.go b/src/runtime/sys_darwin.go
|
diff --git a/src/runtime/sys_darwin.go b/src/runtime/sys_darwin.go
|
||||||
index 06474434c9..6f7ca37122 100644
|
index 4a3f2fc453..4a69403b32 100644
|
||||||
--- a/src/runtime/sys_darwin.go
|
--- a/src/runtime/sys_darwin.go
|
||||||
+++ b/src/runtime/sys_darwin.go
|
+++ b/src/runtime/sys_darwin.go
|
||||||
@@ -469,7 +469,7 @@ func setNonblock(fd int32) {
|
@@ -440,7 +440,7 @@ func setNonblock(fd int32) {
|
||||||
//go:cgo_import_dynamic libc_usleep usleep "/usr/lib/libSystem.B.dylib"
|
//go:cgo_import_dynamic libc_usleep usleep "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
//go:cgo_import_dynamic libc_mach_timebase_info mach_timebase_info "/usr/lib/libSystem.B.dylib"
|
//go:cgo_import_dynamic libc_mach_timebase_info mach_timebase_info "/usr/lib/libSystem.B.dylib"
|
||||||
-//go:cgo_import_dynamic libc_mach_absolute_time mach_absolute_time "/usr/lib/libSystem.B.dylib"
|
-//go:cgo_import_dynamic libc_mach_absolute_time mach_absolute_time "/usr/lib/libSystem.B.dylib"
|
||||||
+//go:cgo_import_dynamic libc_mach_continuous_time mach_continuous_time "/usr/lib/libSystem.B.dylib"
|
+//go:cgo_import_dynamic libc_mach_continuous_time mach_continuous_time "/usr/lib/libSystem.B.dylib"
|
||||||
//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
|
//go:cgo_import_dynamic libc_clock_gettime clock_gettime "/usr/lib/libSystem.B.dylib"
|
||||||
//go:cgo_import_dynamic libc_sigaction sigaction "/usr/lib/libSystem.B.dylib"
|
//go:cgo_import_dynamic libc_sigaction sigaction "/usr/lib/libSystem.B.dylib"
|
||||||
//go:cgo_import_dynamic libc_pthread_sigmask pthread_sigmask "/usr/lib/libSystem.B.dylib"
|
//go:cgo_import_dynamic libc_pthread_sigmask pthread_sigmask "/usr/lib/libSystem.B.dylib"
|
||||||
diff --git a/src/runtime/sys_darwin_amd64.s b/src/runtime/sys_darwin_amd64.s
|
diff --git a/src/runtime/sys_darwin_amd64.s b/src/runtime/sys_darwin_amd64.s
|
||||||
index 825852d673..5a8b994fb1 100644
|
index 630fb5df64..4499c88802 100644
|
||||||
--- a/src/runtime/sys_darwin_amd64.s
|
--- a/src/runtime/sys_darwin_amd64.s
|
||||||
+++ b/src/runtime/sys_darwin_amd64.s
|
+++ b/src/runtime/sys_darwin_amd64.s
|
||||||
@@ -109,7 +109,7 @@ TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
|
@@ -114,7 +114,7 @@ TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
|
||||||
PUSHQ BP
|
PUSHQ BP
|
||||||
MOVQ SP, BP
|
MOVQ SP, BP
|
||||||
MOVQ DI, BX
|
MOVQ DI, BX
|
||||||
@@ -44,10 +44,10 @@ index 825852d673..5a8b994fb1 100644
|
|||||||
MOVL timebase<>+machTimebaseInfo_numer(SB), SI
|
MOVL timebase<>+machTimebaseInfo_numer(SB), SI
|
||||||
MOVL timebase<>+machTimebaseInfo_denom(SB), DI // atomic read
|
MOVL timebase<>+machTimebaseInfo_denom(SB), DI // atomic read
|
||||||
diff --git a/src/runtime/sys_darwin_arm64.s b/src/runtime/sys_darwin_arm64.s
|
diff --git a/src/runtime/sys_darwin_arm64.s b/src/runtime/sys_darwin_arm64.s
|
||||||
index 585d4f2c64..c556d88730 100644
|
index 96d2ed1076..f046545395 100644
|
||||||
--- a/src/runtime/sys_darwin_arm64.s
|
--- a/src/runtime/sys_darwin_arm64.s
|
||||||
+++ b/src/runtime/sys_darwin_arm64.s
|
+++ b/src/runtime/sys_darwin_arm64.s
|
||||||
@@ -135,7 +135,7 @@ GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
|
@@ -143,7 +143,7 @@ GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
|
||||||
|
|
||||||
TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$40
|
TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$40
|
||||||
MOVD R0, R19
|
MOVD R0, R19
|
||||||
@@ -57,5 +57,5 @@ index 585d4f2c64..c556d88730 100644
|
|||||||
MOVW timebase<>+machTimebaseInfo_numer(SB), R20
|
MOVW timebase<>+machTimebaseInfo_numer(SB), R20
|
||||||
MOVD $timebase<>+machTimebaseInfo_denom(SB), R21
|
MOVD $timebase<>+machTimebaseInfo_denom(SB), R21
|
||||||
--
|
--
|
||||||
2.29.2
|
2.30.1
|
||||||
|
|
||||||
|
|||||||
@@ -109,10 +109,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
|||||||
extension WireGuardLogLevel {
|
extension WireGuardLogLevel {
|
||||||
var osLogLevel: OSLogType {
|
var osLogLevel: OSLogType {
|
||||||
switch self {
|
switch self {
|
||||||
case .debug:
|
case .verbose:
|
||||||
return .debug
|
return .debug
|
||||||
case .info:
|
|
||||||
return .info
|
|
||||||
case .error:
|
case .error:
|
||||||
return .error
|
return .error
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user