Compare commits

...

14 Commits

Author SHA1 Message Date
Jason A. Donenfeld 87f0526f09 App: version bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-06-16 18:34:54 +02:00
Jason A. Donenfeld 060c027325 Kit: Go: mod bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-06-16 18:03:28 +02:00
Jason A. Donenfeld 23bf3cfccb Kit: Adapter: use more reliable utun detection technique
Rather than hoping that the AF_SYSTEM fd is of type utun, and then
calling "2" on it to get the name -- which could be defined as something
else for a different AF_SYSTEM socket type -- instead simply query the
AF_SYSTEM control socket ID with getpeername. This has one catch, which
is that the ID is dynamically allocated, so we resolve it using the
qualified name. Normally we'd make a new AF_SYSTEM socket for this, but
since that's not allowed in the sandbox, we reuse the AF_SYSTEM socket
that we're checking. At this point in the flow, we know that it's a
proper AF_SYSTEM one, based on the first sockaddr member; we just don't
know that it's a utun variety.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-06-16 17:40:12 +02:00
Jason A. Donenfeld 7f5ad3e503 Kit: Adapter: iterate through all FDs to find UTUN
This is a bit of a kludge, until I find something better. We simply
iterate through all FDs, and call getsockopt on each one until we find
the utun FD. This works, and completes rather quickly (fd is usually 6
or 7). Rather than maintain the old path for older kernels, just use
this for all versions, to get more coverage. Other techniques involve
undocumented APIs; this one has the advantage of using nothing
undocumented.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-06-16 15:56:21 +02:00
Andrej Mihajlov 820fa55380 SPM: update exclude rules
Fixes missing excluded file warning in Xcode. api-ios.go was renamed to api-apple.go.

Signed-off-by: Andrej Mihajlov <and@mullvad.net>
2021-06-16 15:23:11 +02:00
Jason A. Donenfeld eb528c766b UI: iOS: asynchronously load from NEHotspotNetwork on iOS 14
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-09 09:10:07 -07:00
Jason A. Donenfeld 53235eb38f UI: iOS: clean up visuals in SSID editor
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-09 09:10:07 -07:00
Jason A. Donenfeld b9ff5c2e94 README: account for funky xcode paths
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-09 09:10:07 -07:00
Jason A. Donenfeld b7f69d20b6 Kit: Go: bump to latest API
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-09 09:10:04 -07:00
Andrej Mihajlov 6c4f4109eb UI: iOS: Disable "copy" action on on-demand cells
Signed-off-by: Andrej Mihajlov <and@mullvad.net>
2021-01-11 13:09:41 +01:00
Jason A. Donenfeld 7b5b564a6e Kit: netcfg: add explicit IP mask routes
macOS will use the wrong source address unless we add explicit routes
that mention the self-pointing gateway. Actually, it won't add any
implicit routes on its own, so in order to route the masks of the
addresses, we have to add our own routes explicitly.

However, this still doesn't fix the problem while inside of the network
extension, even though it works outside it.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-01 18:28:14 +01:00
Jason A. Donenfeld 695f868b1f Kit: Go: mod bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-12-23 22:54:47 +01:00
Andrej Mihajlov e724c043d9 UI: iOS: Remove duplicate call to addSubview
Signed-off-by: Andrej Mihajlov <and@mullvad.net>
2020-12-23 16:14:03 +01:00
Andrej Mihajlov 491301f58b UI: iOS: Fix placeholder label alignment in text fields.
Signed-off-by: Andrej Mihajlov <and@mullvad.net>
2020-12-23 16:14:03 +01:00
18 changed files with 276 additions and 128 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ let package = Package(
"goruntime-boottime-over-monotonic.diff",
"go.mod",
"go.sum",
"api-ios.go",
"api-apple.go",
"Makefile"
],
publicHeadersPath: ".",
+1 -1
View File
@@ -54,7 +54,7 @@ $ open WireGuard.xcodeproj
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`.
@@ -109,6 +109,7 @@
"tunnelOnDemandSectionTitleAddSSIDs" = "Add SSIDs";
"tunnelOnDemandAddMessageAddConnectedSSID (%@)" = "Add connected: %@";
"tunnelOnDemandAddMessageAddNewSSID" = "Add new";
"tunnelOnDemandSSIDTextFieldPlaceholder" = "SSID";
"tunnelOnDemandKey" = "On demand";
"tunnelOnDemandOptionOff" = "Off";
+2 -2
View File
@@ -1,2 +1,2 @@
VERSION_NAME = 1.0.12
VERSION_ID = 22
VERSION_NAME = 1.0.13
VERSION_ID = 24
@@ -9,6 +9,11 @@ class EditableTextCell: UITableViewCell {
set(value) { valueTextField.text = value }
}
var placeholder: String? {
get { return valueTextField.placeholder }
set(value) { valueTextField.placeholder = value }
}
let valueTextField: UITextField = {
let valueTextField = UITextField()
valueTextField.textAlignment = .left
@@ -29,12 +34,13 @@ class EditableTextCell: UITableViewCell {
valueTextField.delegate = self
contentView.addSubview(valueTextField)
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
NSLayoutConstraint.activate([
valueTextField.leadingAnchor.constraint(equalToSystemSpacingAfter: contentView.layoutMarginsGuide.leadingAnchor, multiplier: 1),
contentView.layoutMarginsGuide.trailingAnchor.constraint(equalToSystemSpacingAfter: valueTextField.trailingAnchor, multiplier: 1),
valueTextField.topAnchor.constraint(equalToSystemSpacingBelow: contentView.layoutMarginsGuide.topAnchor, multiplier: 1),
valueTextField.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
contentView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: valueTextField.trailingAnchor),
contentView.layoutMarginsGuide.topAnchor.constraint(equalTo: valueTextField.topAnchor),
bottomAnchorConstraint
])
}
@@ -50,6 +56,7 @@ class EditableTextCell: UITableViewCell {
override func prepareForReuse() {
super.prepareForReuse()
message = ""
placeholder = nil
}
}
@@ -27,7 +27,7 @@ class KeyValueCell: UITableViewCell {
}()
let valueTextField: UITextField = {
let valueTextField = UITextField()
let valueTextField = KeyValueCellTextField()
valueTextField.textAlignment = .right
valueTextField.isEnabled = false
valueTextField.font = UIFont.preferredFont(forTextStyle: .body)
@@ -115,8 +115,6 @@ class KeyValueCell: UITableViewCell {
expandToFitValueLabelConstraint.priority = .defaultLow + 1
expandToFitValueLabelConstraint.isActive = true
contentView.addSubview(valueLabelScrollView)
contentView.addSubview(valueLabelScrollView)
valueLabelScrollView.translatesAutoresizingMaskIntoConstraints = false
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)
}
}
@@ -3,6 +3,7 @@
import UIKit
import SystemConfiguration.CaptiveNetwork
import NetworkExtension
protocol SSIDOptionEditTableViewControllerDelegate: class {
func ssidOptionSaved(option: ActivateOnDemandViewModel.OnDemandSSIDOption, ssids: [String])
@@ -39,9 +40,16 @@ class SSIDOptionEditTableViewController: UITableViewController {
selectedOption = option
selectedSSIDs = ssids
super.init(style: .grouped)
connectedSSID = getConnectedSSID()
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) {
@@ -60,6 +68,7 @@ class SSIDOptionEditTableViewController: UITableViewController {
tableView.register(TextCell.self)
tableView.isEditing = true
tableView.allowsSelectionDuringEditing = true
tableView.keyboardDismissMode = .onDrag
}
func loadSections() {
@@ -71,14 +80,14 @@ class SSIDOptionEditTableViewController: UITableViewController {
}
}
func loadAddSSIDRows() {
addSSIDRows.removeAll()
if let connectedSSID = connectedSSID {
if !selectedSSIDs.contains(connectedSSID) {
addSSIDRows.append(.addConnectedSSID(connectedSSID: connectedSSID))
func updateCurrentSSIDEntry() {
if let connectedSSID = connectedSSID, !selectedSSIDs.contains(connectedSSID) {
if let first = addSSIDRows.first, case .addNewSSID = first {
addSSIDRows.insert(.addConnectedSSID(connectedSSID: connectedSSID), at: 0)
}
} else if let first = addSSIDRows.first, case .addConnectedSSID = first {
addSSIDRows.removeFirst()
}
addSSIDRows.append(.addNewSSID)
}
func updateTableViewAddSSIDRows() {
@@ -188,12 +197,13 @@ extension SSIDOptionEditTableViewController {
private func selectedSSIDCell(for tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell {
let cell: EditableTextCell = tableView.dequeueReusableCell(for: indexPath)
cell.message = selectedSSIDs[indexPath.row]
cell.placeholder = tr("tunnelOnDemandSSIDTextFieldPlaceholder")
cell.isEditing = true
cell.onValueBeingEdited = { [weak self, weak cell] text in
guard let self = self, let cell = cell else { return }
if let row = self.tableView.indexPath(for: cell)?.row {
self.selectedSSIDs[row] = text
self.loadAddSSIDRows()
self.updateCurrentSSIDEntry()
self.updateTableViewAddSSIDRows()
}
}
@@ -224,7 +234,7 @@ extension SSIDOptionEditTableViewController {
} else {
tableView.reloadRows(at: [indexPath], with: .automatic)
}
loadAddSSIDRows()
updateCurrentSSIDEntry()
updateTableViewAddSSIDRows()
case .addSSIDs:
assert(editingStyle == .insert)
@@ -244,7 +254,7 @@ extension SSIDOptionEditTableViewController {
} else {
tableView.insertRows(at: [indexPath], with: .automatic)
}
loadAddSSIDRows()
updateCurrentSSIDEntry()
updateTableViewAddSSIDRows()
if newSSID.isEmpty {
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 {
@@ -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)
cell.key = field.localizedUIString
cell.value = onDemandViewModel.localizedInterfaceDescription
cell.copyableGesture = false
return cell
} else {
assert(field == .ssid)
@@ -402,6 +403,7 @@ extension TunnelDetailTableViewController {
let cell: KeyValueCell = tableView.dequeueReusableCell(for: indexPath)
cell.key = field.localizedUIString
cell.value = onDemandViewModel.ssidOption.localizedUIString
cell.copyableGesture = false
return cell
} else {
let cell: ChevronCell = tableView.dequeueReusableCell(for: indexPath)
+48
View File
@@ -64,4 +64,52 @@ extension IPAddressRange {
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)
}
let (ipv4Routes, ipv6Routes) = routes()
let (ipv4Addresses, ipv6Addresses) = addresses()
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
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
networkSettings.ipv6Settings = ipv6Settings
return networkSettings
}
private func ipv4SubnetMaskString(of addressRange: IPAddressRange) -> String {
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]) {
private func addresses() -> ([NEIPv4Route], [NEIPv6Route]) {
var ipv4Routes = [NEIPv4Route]()
var ipv6Routes = [NEIPv6Route]()
for addressRange in tunnelConfiguration.interface.addresses {
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 {
/* 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
@@ -160,10 +148,23 @@ class PacketTunnelSettingsGenerator {
private func includedRoutes() -> ([NEIPv4Route], [NEIPv6Route]) {
var ipv4IncludedRoutes = [NEIPv4Route]()
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 addressRange in peer.allowedIPs {
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 {
ipv6IncludedRoutes.append(NEIPv6Route(destinationAddress: "\(addressRange.address)", networkPrefixLength: NSNumber(value: addressRange.networkPrefixLength)))
}
+42 -12
View File
@@ -57,12 +57,43 @@ public class WireGuardAdapter {
/// Tunnel device file descriptor.
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.
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.
@@ -265,7 +296,7 @@ public class WireGuardAdapter {
.takeUnretainedValue()
let swiftString = String(cString: message).trimmingCharacters(in: .newlines)
let tunnelLogLevel = WireGuardLogLevel(rawValue: logLevel) ?? .debug
let tunnelLogLevel = WireGuardLogLevel(rawValue: logLevel) ?? .verbose
unretainedSelf.logHandler(tunnelLogLevel, swiftString)
}
@@ -369,9 +400,9 @@ public class WireGuardAdapter {
switch result {
case .success((let sourceEndpoint, let resolvedEndpoint)):
if sourceEndpoint.host == resolvedEndpoint.host {
self.logHandler(.debug, "DNS64: mapped \(sourceEndpoint.host) to itself.")
self.logHandler(.verbose, "DNS64: mapped \(sourceEndpoint.host) to itself.")
} 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):
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.
/// - Parameter path: new network path
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 case .started(let handle, _) = self.state {
@@ -399,7 +430,7 @@ public class WireGuardAdapter {
wgDisableSomeRoamingForBrokenMobileSemantics(handle)
wgBumpSockets(handle)
} else {
self.logHandler(.info, "Connectivity offline, pausing backend.")
self.logHandler(.verbose, "Connectivity offline, pausing backend.")
self.state = .temporaryShutdown(settingsGenerator)
wgTurnOff(handle)
@@ -408,7 +439,7 @@ public class WireGuardAdapter {
case .temporaryShutdown(let settingsGenerator):
guard path.status.isSatisfiable else { return }
self.logHandler(.info, "Connectivity online, resuming backend.")
self.logHandler(.verbose, "Connectivity online, resuming backend.")
do {
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 {
case debug = 0
case info = 1
case error = 2
case verbose = 0
case error = 1
}
private extension Network.NWPath.Status {
+15
View File
@@ -3,3 +3,18 @@
#include "key.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];
};
+9 -7
View File
@@ -3,9 +3,9 @@
# 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.
ARCHS ?= x86_64 #TODO: add arm64 to this list once we support apple silicon
SDK_NAME ?= macosx
SDKROOT ?= $(shell xcrun --sdk $(SDK_NAME) --show-sdk-path)
ARCHS ?= x86_64 arm64
PLATFORM_NAME ?= macosx
SDKROOT ?= $(shell xcrun --sdk $(PLATFORM_NAME) --show-sdk-path)
CONFIGURATION_BUILD_DIR ?= $(CURDIR)/out
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
GOARCH_arm64 := arm64
GOARCH_x86_64 := amd64
GOOS_macosx := darwin
GOOS_iphoneos := ios
build: $(DESTDIR)/libwg-go.a
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_CFLAGS := $(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: $(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"
endef
$(foreach ARCH,$(ARCHS),$(eval $(call libwg-go-a,$(ARCH))))
$(DESTDIR)/wireguard-go-version.h: $(GOROOT)/.prepared go.mod
go list -m golang.zx2c4.com/wireguard | sed -n 's/.*v\([0-9.]*\).*/#define WIREGUARD_GO_VERSION "\1"/p' > "$@"
$(DESTDIR)/wireguard-go-version.h: go.mod $(GOROOT)/.prepared
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)
@mkdir -vp "$(DESTDIR)"
@@ -14,36 +14,41 @@ package main
import "C"
import (
"errors"
"log"
"fmt"
"math"
"os"
"os/signal"
"runtime"
"runtime/debug"
"strings"
"time"
"unsafe"
"golang.org/x/sys/unix"
"golang.zx2c4.com/wireguard/conn"
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/tun"
)
var loggerFunc unsafe.Pointer
var loggerCtx unsafe.Pointer
var versionString *C.char
type CLogger struct {
level C.int
type CLogger 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 {
return 0, errors.New("No logger initialized")
return
}
message := C.CString(string(p))
C.callLogger(loggerFunc, loggerCtx, l.level, message)
C.free(unsafe.Pointer(message))
return len(p), nil
C.callLogger(loggerFunc, loggerCtx, C.int(l), cstring(fmt.Sprintf(format, args...)))
}
type tunnelHandle struct {
@@ -54,7 +59,6 @@ type tunnelHandle struct {
var tunnelHandles = make(map[int32]tunnelHandle)
func init() {
versionString = C.CString(device.WireGuardGoVersion)
signals := make(chan os.Signal)
signal.Notify(signals, unix.SIGUSR2)
go func() {
@@ -81,40 +85,39 @@ func wgSetLogger(context, loggerFn uintptr) {
//export wgTurnOn
func wgTurnOn(settings *C.char, tunFd int32) int32 {
logger := &device.Logger{
Debug: log.New(&CLogger{level: 0}, "", 0),
Info: log.New(&CLogger{level: 1}, "", 0),
Error: log.New(&CLogger{level: 2}, "", 0),
Verbosef: CLogger(0).Printf,
Errorf: CLogger(1).Printf,
}
dupTunFd, err := unix.Dup(int(tunFd))
if err != nil {
logger.Error.Println(err)
logger.Errorf("Unable to dup tun fd: %v", err)
return -1
}
err = unix.SetNonblock(dupTunFd, true)
if err != nil {
logger.Error.Println(err)
logger.Errorf("Unable to set tun fd as non blocking: %v", err)
unix.Close(dupTunFd)
return -1
}
tun, err := tun.CreateTUNFromFile(os.NewFile(uintptr(dupTunFd), "/dev/tun"), 0)
if err != nil {
logger.Error.Println(err)
logger.Errorf("Unable to create new tun device from fd: %v", err)
unix.Close(dupTunFd)
return -1
}
logger.Info.Println("Attaching to interface")
dev := device.NewDevice(tun, logger)
logger.Verbosef("Attaching to interface")
dev := device.NewDevice(tun, conn.NewStdNetBind(), logger)
err = dev.IpcSet(C.GoString(settings))
if err != nil {
logger.Error.Println(err)
logger.Errorf("Unable to set IPC settings: %v", err)
unix.Close(dupTunFd)
return -1
}
dev.Up()
logger.Info.Println("Device started")
logger.Verbosef("Device started")
var i int32
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))
if err != nil {
dev.Error.Println(err)
dev.Errorf("Unable to set IPC settings: %v", err)
if ipcErr, ok := err.(*device.IPCError); ok {
return ipcErr.ErrorCode()
}
@@ -183,10 +186,10 @@ func wgBumpSockets(tunnelHandle int32) {
dev.SendKeepalivesToPeersWithCurrentKeypair()
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)
}
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
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() {}
+6 -6
View File
@@ -1,10 +1,10 @@
module golang.zx2c4.com/wireguard/ios
module golang.zx2c4.com/wireguard/apple
go 1.15
go 1.16
require (
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
golang.org/x/net v0.0.0-20201216054612-986b41b23924 // indirect
golang.org/x/sys v0.0.0-20201223074533-0d417f636930
golang.zx2c4.com/wireguard v0.0.20201119-0.20201223104851-e467e07bbf51
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22
golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2
)
+13 -14
View File
@@ -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-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
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-20201216054612-986b41b23924 h1:QsnDpLLOKwHBBDa8nDws4DYNc/ryVW2vCpxCs09d4PY=
golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
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-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-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-20201126233918-771906719818/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-20201223074533-0d417f636930/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/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-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.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.zx2c4.com/wireguard v0.0.20201119-0.20201223104851-e467e07bbf51 h1:F62E0jQdNkXUnELQw+NaOnMxdEnnGScuywq0NdB4YTQ=
golang.zx2c4.com/wireguard v0.0.20201119-0.20201223104851-e467e07bbf51/go.mod h1:ITsWNpkFv78VPB7f8MiyuxeEMcHR4jfxHGCJLPP3GHs=
golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2 h1:wfOOSvHgIzTZ9h5Vb6yUFZNn7uf3bT7PeYsHOO7tYDM=
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>
Date: Wed, 9 Dec 2020 14:07:06 +0100
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(-)
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
+++ 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_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_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_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
index 825852d673..5a8b994fb1 100644
index 630fb5df64..4499c88802 100644
--- a/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
MOVQ SP, BP
MOVQ DI, BX
@@ -44,10 +44,10 @@ index 825852d673..5a8b994fb1 100644
MOVL timebase<>+machTimebaseInfo_numer(SB), SI
MOVL timebase<>+machTimebaseInfo_denom(SB), DI // atomic read
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
+++ 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
MOVD R0, R19
@@ -57,5 +57,5 @@ index 585d4f2c64..c556d88730 100644
MOVW timebase<>+machTimebaseInfo_numer(SB), R20
MOVD $timebase<>+machTimebaseInfo_denom(SB), R21
--
2.29.2
2.30.1
@@ -109,10 +109,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
extension WireGuardLogLevel {
var osLogLevel: OSLogType {
switch self {
case .debug:
case .verbose:
return .debug
case .info:
return .info
case .error:
return .error
}