summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2019-06-14 13:33:08 +0200
committerAndrej Mihajlov <and@mullvad.net>2019-06-14 13:33:08 +0200
commita5626795e89c18f3b7e4ab30f401fb9b0d4a00c9 (patch)
tree56d82fb4ff26a3cf106c97df3a28a275dd27e6c4
parenta48c2d1d52951b911736a02a4ab624a31e4e0cd6 (diff)
parent443d8e3d27be99fe0b1404aaac653f043612cfef (diff)
downloadmullvadvpn-a5626795e89c18f3b7e4ab30f401fb9b0d4a00c9.tar.xz
mullvadvpn-a5626795e89c18f3b7e4ab30f401fb9b0d4a00c9.zip
Merge branch 'add-wireguard-go-ios'
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj125
-rw-r--r--ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/WireGuardGoBridge.xcscheme80
-rw-r--r--ios/MullvadVPN/MullvadVPN-Bridging-Header.h5
-rw-r--r--ios/PacketTunnel/PacketTunnel-Bridging-Header.h6
-rw-r--r--ios/wireguard-go-bridge/Makefile81
-rw-r--r--ios/wireguard-go-bridge/api-ios.go183
-rw-r--r--ios/wireguard-go-bridge/go.mod8
-rw-r--r--ios/wireguard-go-bridge/go.sum23
-rw-r--r--ios/wireguard-go-bridge/goruntime-boottime-over-monotonic.diff87
-rw-r--r--ios/wireguard-go-bridge/goruntime-syscall-remove-getdirentries.diff279
-rw-r--r--ios/wireguard-go-bridge/sys-unix-remove-getdirentries.diff143
-rw-r--r--ios/wireguard-go-bridge/wireguard.h24
12 files changed, 1044 insertions, 0 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index 9d69481c7c..8b44ec32f3 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -20,6 +20,7 @@
58535B85229E89E7004BCBBD /* WeakBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58535B84229E89E7004BCBBD /* WeakBox.swift */; };
5862805422428EF100F5A6E1 /* TranslucentButtonBlurView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5862805322428EF100F5A6E1 /* TranslucentButtonBlurView.swift */; };
5867A51C2248F26A005513C0 /* SegueIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5867A51B2248F26A005513C0 /* SegueIdentifier.swift */; };
+ 58723E7522A54CB2009837F5 /* libwg-go.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58723E7422A54C63009837F5 /* libwg-go.a */; };
587425C12299833500CA2045 /* RootContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587425C02299833500CA2045 /* RootContainerViewController.swift */; };
587B08E0229433EB000E6F17 /* LoginState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B08DF229433EB000E6F17 /* LoginState.swift */; };
587B08E2229460C1000E6F17 /* WebLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B08E1229460C1000E6F17 /* WebLinks.swift */; };
@@ -61,6 +62,13 @@
remoteGlobalIDString = 58CE5E78224146470008646E;
remoteInfo = PacketTunnel;
};
+ 58FBDAA122A52A6800EB69A3 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 58CE5E58224146200008646E /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 58FBDA9722A519BC00EB69A3;
+ remoteInfo = WireGuardGoBridge;
+ };
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -92,6 +100,7 @@
5862805322428EF100F5A6E1 /* TranslucentButtonBlurView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslucentButtonBlurView.swift; sourceTree = "<group>"; };
5866F39B2243B82D00168AE5 /* MullvadVPN.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MullvadVPN.entitlements; sourceTree = "<group>"; };
5867A51B2248F26A005513C0 /* SegueIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegueIdentifier.swift; sourceTree = "<group>"; };
+ 58723E7422A54C63009837F5 /* libwg-go.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libwg-go.a"; sourceTree = BUILT_PRODUCTS_DIR; };
587425C02299833500CA2045 /* RootContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootContainerViewController.swift; sourceTree = "<group>"; };
587B08DF229433EB000E6F17 /* LoginState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginState.swift; sourceTree = "<group>"; };
587B08E1229460C1000E6F17 /* WebLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebLinks.swift; sourceTree = "<group>"; };
@@ -126,6 +135,8 @@
58F19E32228B383300C7710B /* AccountVerificationProcedure.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountVerificationProcedure.swift; sourceTree = "<group>"; };
58F19E34228C15BA00C7710B /* SpinnerActivityIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpinnerActivityIndicatorView.swift; sourceTree = "<group>"; };
58F83F07229D3F560086FCE3 /* AccountExpiryRefresh.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountExpiryRefresh.swift; sourceTree = "<group>"; };
+ 58FBDAA422A52BDA00EB69A3 /* PacketTunnel-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PacketTunnel-Bridging-Header.h"; sourceTree = "<group>"; };
+ 58FBDAAA22A52DC500EB69A3 /* MullvadVPN-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MullvadVPN-Bridging-Header.h"; sourceTree = "<group>"; };
58FFE443228C82A00036F391 /* UserDefaultsInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsInteractor.swift; sourceTree = "<group>"; };
627D4CE562B85202FCFA0EB1 /* Pods-MullvadVPN.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MullvadVPN.debug.xcconfig"; path = "Target Support Files/Pods-MullvadVPN/Pods-MullvadVPN.debug.xcconfig"; sourceTree = "<group>"; };
9F1362F46063B1D06EB0C685 /* Pods-PacketTunnel.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PacketTunnel.debug.xcconfig"; path = "Target Support Files/Pods-PacketTunnel/Pods-PacketTunnel.debug.xcconfig"; sourceTree = "<group>"; };
@@ -147,6 +158,7 @@
buildActionMask = 2147483647;
files = (
543203592C79FAD36BC1E700 /* Pods_PacketTunnel.framework in Frameworks */,
+ 58723E7522A54CB2009837F5 /* libwg-go.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -176,6 +188,7 @@
58CE5E61224146200008646E /* Products */ = {
isa = PBXGroup;
children = (
+ 58723E7422A54C63009837F5 /* libwg-go.a */,
58CE5E60224146200008646E /* MullvadVPN.app */,
58CE5E79224146470008646E /* PacketTunnel.appex */,
);
@@ -227,6 +240,7 @@
581CBCE52296B97300727D7F /* ViewControllerIdentifier.swift */,
58535B84229E89E7004BCBBD /* WeakBox.swift */,
587B08E1229460C1000E6F17 /* WebLinks.swift */,
+ 58FBDAAA22A52DC500EB69A3 /* MullvadVPN-Bridging-Header.h */,
);
path = MullvadVPN;
sourceTree = "<group>";
@@ -237,6 +251,7 @@
58CE5E7B224146470008646E /* PacketTunnelProvider.swift */,
58CE5E7D224146470008646E /* Info.plist */,
58CE5E7E224146470008646E /* PacketTunnel.entitlements */,
+ 58FBDAA422A52BDA00EB69A3 /* PacketTunnel-Bridging-Header.h */,
);
path = PacketTunnel;
sourceTree = "<group>";
@@ -254,12 +269,30 @@
};
/* End PBXGroup section */
+/* Begin PBXLegacyTarget section */
+ 58FBDA9722A519BC00EB69A3 /* WireGuardGoBridge */ = {
+ isa = PBXLegacyTarget;
+ buildArgumentsString = "$(ACTION)";
+ buildConfigurationList = 58FBDA9A22A519BC00EB69A3 /* Build configuration list for PBXLegacyTarget "WireGuardGoBridge" */;
+ buildPhases = (
+ );
+ buildToolPath = /usr/bin/make;
+ buildWorkingDirectory = "$(PROJECT_DIR)/wireguard-go-bridge";
+ dependencies = (
+ );
+ name = WireGuardGoBridge;
+ passBuildSettingsInEnvironment = 1;
+ productName = WireGuardGoBridge;
+ };
+/* End PBXLegacyTarget section */
+
/* Begin PBXNativeTarget section */
58CE5E5F224146200008646E /* MullvadVPN */ = {
isa = PBXNativeTarget;
buildConfigurationList = 58CE5E72224146210008646E /* Build configuration list for PBXNativeTarget "MullvadVPN" */;
buildPhases = (
A4E72CCF49FD4D29D984E1FC /* [CP] Check Pods Manifest.lock */,
+ 58FBDAA922A52D9B00EB69A3 /* Extract wireguard-go Version */,
58CE5E5C224146200008646E /* Sources */,
58CE5E5D224146200008646E /* Frameworks */,
58CE5E5E224146200008646E /* Resources */,
@@ -281,6 +314,7 @@
buildConfigurationList = 58CE5E82224146470008646E /* Build configuration list for PBXNativeTarget "PacketTunnel" */;
buildPhases = (
C8E26D766ABD05BF7B4EB4AC /* [CP] Check Pods Manifest.lock */,
+ 58FBDAA322A52AE700EB69A3 /* Extract wireguard-go Version */,
58CE5E75224146470008646E /* Sources */,
58CE5E76224146470008646E /* Frameworks */,
58CE5E77224146470008646E /* Resources */,
@@ -288,6 +322,7 @@
buildRules = (
);
dependencies = (
+ 58FBDAA222A52A6800EB69A3 /* PBXTargetDependency */,
);
name = PacketTunnel;
productName = PacketTunnel;
@@ -317,6 +352,9 @@
CreatedOnToolsVersion = 10.0;
LastSwiftMigration = 1020;
};
+ 58FBDA9722A519BC00EB69A3 = {
+ CreatedOnToolsVersion = 10.2.1;
+ };
};
};
buildConfigurationList = 58CE5E5B224146200008646E /* Build configuration list for PBXProject "MullvadVPN" */;
@@ -334,6 +372,7 @@
targets = (
58CE5E5F224146200008646E /* MullvadVPN */,
58CE5E78224146470008646E /* PacketTunnel */,
+ 58FBDA9722A519BC00EB69A3 /* WireGuardGoBridge */,
);
};
/* End PBXProject section */
@@ -381,6 +420,43 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MullvadVPN/Pods-MullvadVPN-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
+ 58FBDAA322A52AE700EB69A3 /* Extract wireguard-go Version */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ );
+ name = "Extract wireguard-go Version";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "exec make -C \"$PROJECT_DIR/wireguard-go-bridge\" version-header\n";
+ showEnvVarsInLog = 0;
+ };
+ 58FBDAA922A52D9B00EB69A3 /* Extract wireguard-go Version */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ );
+ name = "Extract wireguard-go Version";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "exec make -C \"$PROJECT_DIR/wireguard-go-bridge\" version-header\n";
+ };
A4E72CCF49FD4D29D984E1FC /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -488,6 +564,11 @@
target = 58CE5E78224146470008646E /* PacketTunnel */;
targetProxy = 58CE5E7F224146470008646E /* PBXContainerItemProxy */;
};
+ 58FBDAA222A52A6800EB69A3 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 58FBDA9722A519BC00EB69A3 /* WireGuardGoBridge */;
+ targetProxy = 58FBDAA122A52A6800EB69A3 /* PBXContainerItemProxy */;
+ };
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@@ -632,6 +713,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = MullvadVPN/MullvadVPN.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
@@ -644,6 +726,8 @@
PRODUCT_BUNDLE_IDENTIFIER = net.mullvad.MullvadVPN;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_OBJC_BRIDGING_HEADER = "MullvadVPN/MullvadVPN-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
@@ -655,6 +739,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = MullvadVPN/MullvadVPN.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
@@ -667,6 +752,7 @@
PRODUCT_BUNDLE_IDENTIFIER = net.mullvad.MullvadVPN;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_OBJC_BRIDGING_HEADER = "MullvadVPN/MullvadVPN-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
@@ -676,6 +762,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 9F1362F46063B1D06EB0C685 /* Pods-PacketTunnel.debug.xcconfig */;
buildSettings = {
+ CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = PacketTunnel/PacketTunnel.entitlements;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = G7CDBEG477;
@@ -688,6 +775,8 @@
PRODUCT_BUNDLE_IDENTIFIER = net.mullvad.MullvadVPN.PacketTunnel;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
+ SWIFT_OBJC_BRIDGING_HEADER = "PacketTunnel/PacketTunnel-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
@@ -697,6 +786,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 40D54D8A8B75B67DC37C5CCE /* Pods-PacketTunnel.release.xcconfig */;
buildSettings = {
+ CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = PacketTunnel/PacketTunnel.entitlements;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = G7CDBEG477;
@@ -709,11 +799,37 @@
PRODUCT_BUNDLE_IDENTIFIER = net.mullvad.MullvadVPN.PacketTunnel;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
+ SWIFT_OBJC_BRIDGING_HEADER = "PacketTunnel/PacketTunnel-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
+ 58FBDA9822A519BC00EB69A3 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ DEBUGGING_SYMBOLS = YES;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 58FBDA9922A519BC00EB69A3 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -744,6 +860,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 58FBDA9A22A519BC00EB69A3 /* Build configuration list for PBXLegacyTarget "WireGuardGoBridge" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 58FBDA9822A519BC00EB69A3 /* Debug */,
+ 58FBDA9922A519BC00EB69A3 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
/* End XCConfigurationList section */
};
rootObject = 58CE5E58224146200008646E /* Project object */;
diff --git a/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/WireGuardGoBridge.xcscheme b/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/WireGuardGoBridge.xcscheme
new file mode 100644
index 0000000000..19216367a9
--- /dev/null
+++ b/ios/MullvadVPN.xcodeproj/xcshareddata/xcschemes/WireGuardGoBridge.xcscheme
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "1020"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "58FBDA9722A519BC00EB69A3"
+ BuildableName = "WireGuardGoBridge"
+ BlueprintName = "WireGuardGoBridge"
+ ReferencedContainer = "container:MullvadVPN.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ </Testables>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "58FBDA9722A519BC00EB69A3"
+ BuildableName = "WireGuardGoBridge"
+ BlueprintName = "WireGuardGoBridge"
+ ReferencedContainer = "container:MullvadVPN.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "58FBDA9722A519BC00EB69A3"
+ BuildableName = "WireGuardGoBridge"
+ BlueprintName = "WireGuardGoBridge"
+ ReferencedContainer = "container:MullvadVPN.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/ios/MullvadVPN/MullvadVPN-Bridging-Header.h b/ios/MullvadVPN/MullvadVPN-Bridging-Header.h
new file mode 100644
index 0000000000..fcd44b3f57
--- /dev/null
+++ b/ios/MullvadVPN/MullvadVPN-Bridging-Header.h
@@ -0,0 +1,5 @@
+//
+// Use this file to import your target's public headers that you would like to expose to Swift.
+//
+
+#include "wireguard-go-version.h"
diff --git a/ios/PacketTunnel/PacketTunnel-Bridging-Header.h b/ios/PacketTunnel/PacketTunnel-Bridging-Header.h
new file mode 100644
index 0000000000..207551c8bb
--- /dev/null
+++ b/ios/PacketTunnel/PacketTunnel-Bridging-Header.h
@@ -0,0 +1,6 @@
+//
+// Use this file to import your target's public headers that you would like to expose to Swift.
+//
+
+#include "../wireguard-go-bridge/wireguard.h"
+#include "wireguard-go-version.h"
diff --git a/ios/wireguard-go-bridge/Makefile b/ios/wireguard-go-bridge/Makefile
new file mode 100644
index 0000000000..4b07394355
--- /dev/null
+++ b/ios/wireguard-go-bridge/Makefile
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# 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 ?= arm64 armv7
+SDK_NAME ?= iphoneos
+SDKROOT ?= $(shell xcrun --sdk $(SDK_NAME) --show-sdk-path)
+CONFIGURATION_BUILD_DIR ?= $(CURDIR)/out
+CONFIGURATION_TEMP_DIR ?= $(CURDIR)/.tmp
+
+export CC ?= clang
+LIPO ?= lipo
+DESTDIR ?= $(CONFIGURATION_BUILD_DIR)
+BUILDDIR ?= $(CONFIGURATION_TEMP_DIR)/wireguard-go-bridge
+
+UPSTREAM_FILES := $(filter-out %/main.go %/queueconstants.go,$(wildcard ../wireguard-go/*/*.go) $(wildcard ../wireguard-go/*.go)) ../wireguard-go/go.mod ../wireguard-go/go.sum
+DOWNSTREAM_FILES := $(wildcard src/*.go) $(wildcard src/*/*.go)
+CFLAGS_PREFIX := $(if $(DEPLOYMENT_TARGET_CLANG_FLAG_NAME),-$(DEPLOYMENT_TARGET_CLANG_FLAG_NAME)=$($(DEPLOYMENT_TARGET_CLANG_ENV_NAME)),) -Wno-unused-command-line-argument -isysroot $(SDKROOT) -arch
+GOARCH_arm64 := arm64
+GOARCH_armv7 := arm
+GOARCH_x86_64 := amd64
+export GOOS := darwin
+export CGO_ENABLED := 1
+
+build: $(DESTDIR)/libwg-go.a
+version-header: $(DESTDIR)/wireguard-go-version.h
+
+GOBUILDVERSION_NEEDED := go version go1.12.5 darwin/amd64
+GOBUILDVERSION_CURRENT := $(shell go version 2>/dev/null)
+export REAL_GOROOT := $(shell go env GOROOT 2>/dev/null)
+export GOROOT := $(BUILDDIR)/goroot
+export GOPATH := $(BUILDDIR)/gopath
+export PATH := $(GOPATH)/bin:$(PATH)
+GOBUILDVERSION_FAKE := $(shell $(GOROOT)/bin/go version 2>/dev/null)
+ifneq ($(GOBUILDVERSION_NEEDED),$(GOBUILDVERSION_CURRENT))
+$(error This requires $(GOBUILDVERSION_NEEDED))
+endif
+ifneq ($(GOBUILDVERSION_NEEDED),$(GOBUILDVERSION_FAKE))
+$(shell rm -f $(GOROOT)/.prepared)
+endif
+
+$(GOROOT)/.prepared:
+ [ -n "$(REAL_GOROOT)" ]
+ mkdir -p "$(GOROOT)"
+ rsync -a --delete --exclude=pkg/obj/go-build "$(REAL_GOROOT)/" "$(GOROOT)/"
+ cat goruntime-*.diff | patch -p1 -f -N -r- -d "$(GOROOT)"
+ rm -rf "$(GOPATH)/pkg/mod"
+ go get -d -tags ios; chmod -fR +w "$(GOPATH)/pkg/mod"
+ for sys in "$(GOPATH)/pkg/mod/golang.org/x/sys@"*; do cat sys-unix-*.diff | patch -p1 -f -N -r- -d "$$sys"; done
+ touch "$@"
+
+$(shell test "$$(cat "$(BUILDDIR)/.gobuildversion" 2>/dev/null)" = "$(GOBUILDVERSION_CURRENT)" || rm -f "$(DESTDIR)/libwg-go.a")
+
+define libwg-go-a
+$(BUILDDIR)/libwg-go-$(1).a: $(GOROOT)/.prepared
+ CGO_CFLAGS="$(CFLAGS_PREFIX) $(ARCH)" \
+ CGO_LDFLAGS="$(CFLAGS_PREFIX) $(ARCH)" \
+ GOARCH="$(GOARCH_$(1))" \
+ go build -tags ios -ldflags=-w -v -o "$(BUILDDIR)/libwg-go-$(1).a" -buildmode c-archive && go version > "$(BUILDDIR)/.gobuildversion"; \
+ chmod -fR +w "$(GOPATH)/pkg/mod"; \
+ ret=$$$$?; \
+ rm -f "$(BUILDDIR)/libwg-go-$(1).h"; \
+ exit $$$$ret
+endef
+$(foreach ARCH,$(ARCHS),$(eval $(call libwg-go-a,$(ARCH))))
+
+$(DESTDIR)/wireguard-go-version.h: go.mod $(GOROOT)/.prepared
+ wggo="$(GOPATH)/pkg/mod/$$(sed -n 's/.*\(golang\.zx2c4\.com\/wireguard\) \(.*\)$$/\1@\2/p' go.mod)"; \
+ sed -n 's/.*WireGuardGoVersion = "\(.*\)"/#define WIREGUARD_GO_VERSION "\1"/p' "$$wggo/device/version.go" > "$@"
+
+$(DESTDIR)/libwg-go.a: $(foreach ARCH,$(ARCHS),$(BUILDDIR)/libwg-go-$(ARCH).a)
+ @mkdir -vp "$(DESTDIR)"
+ $(LIPO) -create -output "$@" $^
+
+clean:
+ rm -rf "$(BUILDDIR)" "$(DESTDIR)/libwg-go.a" "$(DESTDIR)/wireguard-go-version.h"
+
+install: build
+
+.PHONY: clean build version-header install
diff --git a/ios/wireguard-go-bridge/api-ios.go b/ios/wireguard-go-bridge/api-ios.go
new file mode 100644
index 0000000000..c98e3d5b60
--- /dev/null
+++ b/ios/wireguard-go-bridge/api-ios.go
@@ -0,0 +1,183 @@
+/* SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2018-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ */
+
+package main
+
+// #include <stdlib.h>
+// #include <sys/types.h>
+// static void callLogger(void *func, int level, const char *msg)
+// {
+// ((void(*)(int, const char *))func)(level, msg);
+// }
+import "C"
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "golang.org/x/sys/unix"
+ "golang.zx2c4.com/wireguard/device"
+ "golang.zx2c4.com/wireguard/tun"
+ "log"
+ "math"
+ "os"
+ "os/signal"
+ "runtime"
+ "strings"
+ "unsafe"
+)
+
+var loggerFunc unsafe.Pointer
+var versionString *C.char
+
+type CLogger struct {
+ level C.int
+}
+
+func (l *CLogger) Write(p []byte) (int, error) {
+ if uintptr(loggerFunc) == 0 {
+ return 0, errors.New("No logger initialized")
+ }
+ message := C.CString(string(p))
+ C.callLogger(loggerFunc, l.level, message)
+ C.free(unsafe.Pointer(message))
+ return len(p), nil
+}
+
+type tunnelHandle struct {
+ *device.Device
+ *device.Logger
+}
+
+var tunnelHandles = make(map[int32]tunnelHandle)
+
+func init() {
+ versionString = C.CString(device.WireGuardGoVersion)
+ device.RoamingDisabled = true
+ signals := make(chan os.Signal)
+ signal.Notify(signals, unix.SIGUSR2)
+ go func() {
+ buf := make([]byte, os.Getpagesize())
+ for {
+ select {
+ case <-signals:
+ n := runtime.Stack(buf, true)
+ buf[n] = 0
+ if uintptr(loggerFunc) != 0 {
+ C.callLogger(loggerFunc, 0, (*C.char)(unsafe.Pointer(&buf[0])))
+ }
+ }
+ }
+ }()
+}
+
+//export wgEnableRoaming
+func wgEnableRoaming(enabled bool) {
+ device.RoamingDisabled = !enabled
+}
+
+//export wgSetLogger
+func wgSetLogger(loggerFn uintptr) {
+ loggerFunc = unsafe.Pointer(loggerFn)
+}
+
+//export wgTurnOn
+func wgTurnOn(settings string, 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),
+ }
+
+ err := unix.SetNonblock(int(tunFd), true)
+ if err != nil {
+ logger.Error.Println(err)
+ return -1
+ }
+ tun, err := tun.CreateTUNFromFile(os.NewFile(uintptr(tunFd), "/dev/tun"), 0)
+ if err != nil {
+ logger.Error.Println(err)
+ return -1
+ }
+ logger.Info.Println("Attaching to interface")
+ device := device.NewDevice(tun, logger)
+
+ setError := device.IpcSetOperation(bufio.NewReader(strings.NewReader(settings)))
+ if setError != nil {
+ logger.Error.Println(setError)
+ return -1
+ }
+
+ device.Up()
+ logger.Info.Println("Device started")
+
+ var i int32
+ for i = 0; i < math.MaxInt32; i++ {
+ if _, exists := tunnelHandles[i]; !exists {
+ break
+ }
+ }
+ if i == math.MaxInt32 {
+ return -1
+ }
+ tunnelHandles[i] = tunnelHandle{device, logger}
+ return i
+}
+
+//export wgTurnOff
+func wgTurnOff(tunnelHandle int32) {
+ device, ok := tunnelHandles[tunnelHandle]
+ if !ok {
+ return
+ }
+ delete(tunnelHandles, tunnelHandle)
+ device.Close()
+}
+
+//export wgSetConfig
+func wgSetConfig(tunnelHandle int32, settings string) int64 {
+ device, ok := tunnelHandles[tunnelHandle]
+ if !ok {
+ return 0
+ }
+ err := device.IpcSetOperation(bufio.NewReader(strings.NewReader(settings)))
+ if err != nil {
+ device.Error.Println(err)
+ return err.ErrorCode()
+ }
+ return 0
+}
+
+//export wgGetConfig
+func wgGetConfig(tunnelHandle int32) *C.char {
+ device, ok := tunnelHandles[tunnelHandle]
+ if !ok {
+ return nil
+ }
+ settings := new(bytes.Buffer)
+ writer := bufio.NewWriter(settings)
+ err := device.IpcGetOperation(writer)
+ if err != nil {
+ return nil
+ }
+ writer.Flush()
+ return C.CString(settings.String())
+}
+//export wgBumpSockets
+func wgBumpSockets(tunnelHandle int32) {
+ device, ok := tunnelHandles[tunnelHandle]
+ if !ok {
+ return
+ }
+ device.BindUpdate()
+ device.SendKeepalivesToPeersWithCurrentKeypair()
+}
+
+//export wgVersion
+func wgVersion() *C.char {
+ return versionString
+}
+
+func main() {}
diff --git a/ios/wireguard-go-bridge/go.mod b/ios/wireguard-go-bridge/go.mod
new file mode 100644
index 0000000000..124bddf02c
--- /dev/null
+++ b/ios/wireguard-go-bridge/go.mod
@@ -0,0 +1,8 @@
+module golang.zx2c4.com/wireguard/ios
+
+go 1.12
+
+require (
+ golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5
+ golang.zx2c4.com/wireguard v0.0.20190518-0.20190530131616-d9f995209c3c
+)
diff --git a/ios/wireguard-go-bridge/go.sum b/ios/wireguard-go-bridge/go.sum
new file mode 100644
index 0000000000..a0ccbea792
--- /dev/null
+++ b/ios/wireguard-go-bridge/go.sum
@@ -0,0 +1,23 @@
+github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576 h1:aUX/1G2gFSs4AsJJg2cL3HuoRhCSCz733FE5GUSuaT4=
+golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo=
+golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53 h1:kcXqo9vE6fsZY5X5Rd7R1l7fTgnWaDCVmln65REefiE=
+golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67 h1:1Fzlr8kkDLQwqMP8GxrhptBLqZG/EDpiATneiZHY998=
+golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5 h1:f005F/Jl5JLP036x7QIvUVhNTqxvSYwFIiyOh2q12iU=
+golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.zx2c4.com/wireguard v0.0.0-20190409083948-18fa27047265 h1:ujM5BaP4MD/2MJZ1n7pmw6IIsyyS7SyPl0fDefnx/2o=
+golang.zx2c4.com/wireguard v0.0.0-20190409083948-18fa27047265/go.mod h1:u0Cl3X+pyWdXaax3S583DQrnGDuTASO0QdlKFrs8r/8=
+golang.zx2c4.com/wireguard v0.0.20190518-0.20190530131616-d9f995209c3c h1:nUKiRKxUjK8Zghs+JBZZYXo0g51BlXVqkr6mDfm22ow=
+golang.zx2c4.com/wireguard v0.0.20190518-0.20190530131616-d9f995209c3c/go.mod h1:8X7vp4RrsvM83bde6vQ94DsL4ZpjUViVUym8aa8zGhs=
diff --git a/ios/wireguard-go-bridge/goruntime-boottime-over-monotonic.diff b/ios/wireguard-go-bridge/goruntime-boottime-over-monotonic.diff
new file mode 100644
index 0000000000..e449ac4e11
--- /dev/null
+++ b/ios/wireguard-go-bridge/goruntime-boottime-over-monotonic.diff
@@ -0,0 +1,87 @@
+From 74523c5a12d37fa792e77a252bcc569484c3d41a Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Wed, 27 Feb 2019 05:33:01 +0100
+Subject: [PATCH] runtime: use libc_mach_continuous_time in nanotime on Darwin
+
+This makes timers account for having expired while a computer was
+asleep, which is quite common on mobile devices. Note that
+continuous_time absolute_time, except that it takes into account
+time spent in suspend.
+
+Fixes #24595
+---
+ src/runtime/sys_darwin.go | 2 +-
+ src/runtime/sys_darwin_386.s | 2 +-
+ src/runtime/sys_darwin_amd64.s | 2 +-
+ src/runtime/sys_darwin_arm.s | 2 +-
+ src/runtime/sys_darwin_arm64.s | 2 +-
+ 5 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/runtime/sys_darwin.go b/src/runtime/sys_darwin.go
+index f34ac88352..416fcb673f 100644
+--- a/src/runtime/sys_darwin.go
++++ b/src/runtime/sys_darwin.go
+@@ -403,7 +403,7 @@ func closeonexec(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_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_386.s b/src/runtime/sys_darwin_386.s
+index 1bc1a63c28..34a3561350 100644
+--- a/src/runtime/sys_darwin_386.s
++++ b/src/runtime/sys_darwin_386.s
+@@ -184,7 +184,7 @@ TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
+ PUSHL BP
+ MOVL SP, BP
+ SUBL $8+(machTimebaseInfo__size+15)/16*16, SP
+- CALL libc_mach_absolute_time(SB)
++ CALL libc_mach_continuous_time(SB)
+ MOVL 16+(machTimebaseInfo__size+15)/16*16(SP), CX
+ MOVL AX, 0(CX)
+ MOVL DX, 4(CX)
+diff --git a/src/runtime/sys_darwin_amd64.s b/src/runtime/sys_darwin_amd64.s
+index f99cb00ab8..8b99316983 100644
+--- a/src/runtime/sys_darwin_amd64.s
++++ b/src/runtime/sys_darwin_amd64.s
+@@ -86,7 +86,7 @@ TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
+ PUSHQ BP
+ MOVQ SP, BP
+ MOVQ DI, BX
+- CALL libc_mach_absolute_time(SB)
++ CALL libc_mach_continuous_time(SB)
+ MOVQ AX, 0(BX)
+ MOVL timebase<>+machTimebaseInfo_numer(SB), SI
+ MOVL timebase<>+machTimebaseInfo_denom(SB), DI // atomic read
+diff --git a/src/runtime/sys_darwin_arm.s b/src/runtime/sys_darwin_arm.s
+index 54c7afbf34..a4f06fdb85 100644
+--- a/src/runtime/sys_darwin_arm.s
++++ b/src/runtime/sys_darwin_arm.s
+@@ -118,7 +118,7 @@ GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
+
+ TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
+ MOVW R0, R8
+- BL libc_mach_absolute_time(SB)
++ BL libc_mach_continuous_time(SB)
+ MOVW R0, 0(R8)
+ MOVW R1, 4(R8)
+ MOVW timebase<>+machTimebaseInfo_numer(SB), R6
+diff --git a/src/runtime/sys_darwin_arm64.s b/src/runtime/sys_darwin_arm64.s
+index 29951d8ad7..cdaf0a630e 100644
+--- a/src/runtime/sys_darwin_arm64.s
++++ b/src/runtime/sys_darwin_arm64.s
+@@ -113,7 +113,7 @@ GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
+
+ TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$40
+ MOVD R0, R19
+- BL libc_mach_absolute_time(SB)
++ BL libc_mach_continuous_time(SB)
+ MOVD R0, 0(R19)
+ MOVW timebase<>+machTimebaseInfo_numer(SB), R20
+ MOVD $timebase<>+machTimebaseInfo_denom(SB), R21
+--
+2.20.1
+
diff --git a/ios/wireguard-go-bridge/goruntime-syscall-remove-getdirentries.diff b/ios/wireguard-go-bridge/goruntime-syscall-remove-getdirentries.diff
new file mode 100644
index 0000000000..a502fbb832
--- /dev/null
+++ b/ios/wireguard-go-bridge/goruntime-syscall-remove-getdirentries.diff
@@ -0,0 +1,279 @@
+From bc77ad792117829909eeeca3aa492d6f292d004d Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Tue, 19 Mar 2019 13:55:44 -0600
+Subject: [PATCH] syscall: do not link against ___getdirentries64
+
+---
+ .../x/sys/unix/syscall_darwin_386.go | 5 ++++-
+ .../x/sys/unix/syscall_darwin_amd64.go | 5 ++++-
+ .../x/sys/unix/zsyscall_darwin_386.go | 22 -------------------
+ .../x/sys/unix/zsyscall_darwin_386.s | 2 --
+ .../x/sys/unix/zsyscall_darwin_amd64.go | 22 -------------------
+ .../x/sys/unix/zsyscall_darwin_amd64.s | 2 --
+ src/syscall/syscall_darwin_386.go | 5 ++++-
+ src/syscall/syscall_darwin_amd64.go | 5 ++++-
+ src/syscall/zsyscall_darwin_386.go | 20 -----------------
+ src/syscall/zsyscall_darwin_386.s | 2 --
+ src/syscall/zsyscall_darwin_amd64.go | 20 -----------------
+ src/syscall/zsyscall_darwin_amd64.s | 2 --
+ 12 files changed, 16 insertions(+), 96 deletions(-)
+
+diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go
+index 489726fa9b..900dd7c91f 100644
+--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go
++++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go
+@@ -56,8 +56,11 @@ const SYS___SYSCTL = SYS_SYSCTL
+ //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
+ //sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
+ //sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
+-//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
+ //sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64
+ //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
+ //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
+ //sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
++
++func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
++ return 0, ENOSYS
++}
+diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
+index 914b89bde5..95e245fff7 100644
+--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
++++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
+@@ -56,8 +56,11 @@ const SYS___SYSCTL = SYS_SYSCTL
+ //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
+ //sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
+ //sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
+-//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
+ //sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64
+ //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
+ //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
+ //sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
++
++func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
++ return 0, ENOSYS
++}
+diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
+index 23346dc68f..db4f1eaf1c 100644
+--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
++++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
+@@ -2408,28 +2408,6 @@ func libc_fstatfs64_trampoline()
+
+ // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+- var _p0 unsafe.Pointer
+- if len(buf) > 0 {
+- _p0 = unsafe.Pointer(&buf[0])
+- } else {
+- _p0 = unsafe.Pointer(&_zero)
+- }
+- r0, _, e1 := syscall_syscall6(funcPC(libc___getdirentries64_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+- n = int(r0)
+- if e1 != 0 {
+- err = errnoErr(e1)
+- }
+- return
+-}
+-
+-func libc___getdirentries64_trampoline()
+-
+-//go:linkname libc___getdirentries64 libc___getdirentries64
+-//go:cgo_import_dynamic libc___getdirentries64 __getdirentries64 "/usr/lib/libSystem.B.dylib"
+-
+-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+-
+ func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) {
+ r0, _, e1 := syscall_syscall(funcPC(libc_getfsstat64_trampoline), uintptr(buf), uintptr(size), uintptr(flags))
+ n = int(r0)
+diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s
+index 37b85b4f61..6165f70e33 100644
+--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s
++++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s
+@@ -272,8 +272,6 @@ TEXT ·libc_fstatat64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_fstatat64(SB)
+ TEXT ·libc_fstatfs64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_fstatfs64(SB)
+-TEXT ·libc___getdirentries64_trampoline(SB),NOSPLIT,$0-0
+- JMP libc___getdirentries64(SB)
+ TEXT ·libc_getfsstat64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_getfsstat64(SB)
+ TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0
+diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
+index b50178d679..dea5dee75e 100644
+--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
++++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
+@@ -2408,28 +2408,6 @@ func libc_fstatfs64_trampoline()
+
+ // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+- var _p0 unsafe.Pointer
+- if len(buf) > 0 {
+- _p0 = unsafe.Pointer(&buf[0])
+- } else {
+- _p0 = unsafe.Pointer(&_zero)
+- }
+- r0, _, e1 := syscall_syscall6(funcPC(libc___getdirentries64_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+- n = int(r0)
+- if e1 != 0 {
+- err = errnoErr(e1)
+- }
+- return
+-}
+-
+-func libc___getdirentries64_trampoline()
+-
+-//go:linkname libc___getdirentries64 libc___getdirentries64
+-//go:cgo_import_dynamic libc___getdirentries64 __getdirentries64 "/usr/lib/libSystem.B.dylib"
+-
+-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+-
+ func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) {
+ r0, _, e1 := syscall_syscall(funcPC(libc_getfsstat64_trampoline), uintptr(buf), uintptr(size), uintptr(flags))
+ n = int(r0)
+diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
+index da9b900a8c..f1e2d7e9a4 100644
+--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
++++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
+@@ -272,8 +272,6 @@ TEXT ·libc_fstatat64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_fstatat64(SB)
+ TEXT ·libc_fstatfs64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_fstatfs64(SB)
+-TEXT ·libc___getdirentries64_trampoline(SB),NOSPLIT,$0-0
+- JMP libc___getdirentries64(SB)
+ TEXT ·libc_getfsstat64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_getfsstat64(SB)
+ TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0
+diff --git a/src/syscall/syscall_darwin_386.go b/src/syscall/syscall_darwin_386.go
+index 045ebc726b..826d76f569 100644
+--- a/src/syscall/syscall_darwin_386.go
++++ b/src/syscall/syscall_darwin_386.go
+@@ -16,7 +16,6 @@ func setTimeval(sec, usec int64) Timeval {
+
+ //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_fstat64
+ //sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_fstatfs64
+-//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS___getdirentries64
+ //sysnb Gettimeofday(tp *Timeval) (err error)
+ //sys Lstat(path string, stat *Stat_t) (err error) = SYS_lstat64
+ //sys Stat(path string, stat *Stat_t) (err error) = SYS_stat64
+@@ -63,3 +62,7 @@ func libc_sendfile_trampoline()
+ func syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
+
+ func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) // sic
++
++func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
++ return 0, ENOSYS
++}
+diff --git a/src/syscall/syscall_darwin_amd64.go b/src/syscall/syscall_darwin_amd64.go
+index 7b6493bf9f..3868790049 100644
+--- a/src/syscall/syscall_darwin_amd64.go
++++ b/src/syscall/syscall_darwin_amd64.go
+@@ -16,7 +16,6 @@ func setTimeval(sec, usec int64) Timeval {
+
+ //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_fstat64
+ //sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_fstatfs64
+-//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS___getdirentries64
+ //sysnb Gettimeofday(tp *Timeval) (err error)
+ //sys Lstat(path string, stat *Stat_t) (err error) = SYS_lstat64
+ //sys Stat(path string, stat *Stat_t) (err error) = SYS_stat64
+@@ -63,3 +62,7 @@ func libc_sendfile_trampoline()
+ func syscallX(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
+
+ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
++
++func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
++ return 0, ENOSYS
++}
+diff --git a/src/syscall/zsyscall_darwin_386.go b/src/syscall/zsyscall_darwin_386.go
+index 758ff7b129..a666a1f65e 100644
+--- a/src/syscall/zsyscall_darwin_386.go
++++ b/src/syscall/zsyscall_darwin_386.go
+@@ -1845,27 +1845,7 @@ func libc_fstatfs64_trampoline()
+
+ //go:linkname libc_fstatfs64 libc_fstatfs64
+ //go:cgo_import_dynamic libc_fstatfs64 fstatfs64 "/usr/lib/libSystem.B.dylib"
+-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+-
+-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+- var _p0 unsafe.Pointer
+- if len(buf) > 0 {
+- _p0 = unsafe.Pointer(&buf[0])
+- } else {
+- _p0 = unsafe.Pointer(&_zero)
+- }
+- r0, _, e1 := syscall6(funcPC(libc___getdirentries64_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+- n = int(r0)
+- if e1 != 0 {
+- err = errnoErr(e1)
+- }
+- return
+-}
+-
+-func libc___getdirentries64_trampoline()
+
+-//go:linkname libc___getdirentries64 libc___getdirentries64
+-//go:cgo_import_dynamic libc___getdirentries64 __getdirentries64 "/usr/lib/libSystem.B.dylib"
+ // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+ func Gettimeofday(tp *Timeval) (err error) {
+diff --git a/src/syscall/zsyscall_darwin_386.s b/src/syscall/zsyscall_darwin_386.s
+index a688192501..a5af9b64b9 100644
+--- a/src/syscall/zsyscall_darwin_386.s
++++ b/src/syscall/zsyscall_darwin_386.s
+@@ -235,8 +235,6 @@ TEXT ·libc_fstat64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_fstat64(SB)
+ TEXT ·libc_fstatfs64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_fstatfs64(SB)
+-TEXT ·libc___getdirentries64_trampoline(SB),NOSPLIT,$0-0
+- JMP libc___getdirentries64(SB)
+ TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_gettimeofday(SB)
+ TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0
+diff --git a/src/syscall/zsyscall_darwin_amd64.go b/src/syscall/zsyscall_darwin_amd64.go
+index afc3d72d8d..bb87aef1f9 100644
+--- a/src/syscall/zsyscall_darwin_amd64.go
++++ b/src/syscall/zsyscall_darwin_amd64.go
+@@ -1845,27 +1845,7 @@ func libc_fstatfs64_trampoline()
+
+ //go:linkname libc_fstatfs64 libc_fstatfs64
+ //go:cgo_import_dynamic libc_fstatfs64 fstatfs64 "/usr/lib/libSystem.B.dylib"
+-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+-
+-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+- var _p0 unsafe.Pointer
+- if len(buf) > 0 {
+- _p0 = unsafe.Pointer(&buf[0])
+- } else {
+- _p0 = unsafe.Pointer(&_zero)
+- }
+- r0, _, e1 := syscall6(funcPC(libc___getdirentries64_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+- n = int(r0)
+- if e1 != 0 {
+- err = errnoErr(e1)
+- }
+- return
+-}
+-
+-func libc___getdirentries64_trampoline()
+
+-//go:linkname libc___getdirentries64 libc___getdirentries64
+-//go:cgo_import_dynamic libc___getdirentries64 __getdirentries64 "/usr/lib/libSystem.B.dylib"
+ // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+ func Gettimeofday(tp *Timeval) (err error) {
+diff --git a/src/syscall/zsyscall_darwin_amd64.s b/src/syscall/zsyscall_darwin_amd64.s
+index 21ab38e3ee..409320dea5 100644
+--- a/src/syscall/zsyscall_darwin_amd64.s
++++ b/src/syscall/zsyscall_darwin_amd64.s
+@@ -235,8 +235,6 @@ TEXT ·libc_fstat64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_fstat64(SB)
+ TEXT ·libc_fstatfs64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_fstatfs64(SB)
+-TEXT ·libc___getdirentries64_trampoline(SB),NOSPLIT,$0-0
+- JMP libc___getdirentries64(SB)
+ TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_gettimeofday(SB)
+ TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0
+--
+2.21.0
+
diff --git a/ios/wireguard-go-bridge/sys-unix-remove-getdirentries.diff b/ios/wireguard-go-bridge/sys-unix-remove-getdirentries.diff
new file mode 100644
index 0000000000..2df5a943e4
--- /dev/null
+++ b/ios/wireguard-go-bridge/sys-unix-remove-getdirentries.diff
@@ -0,0 +1,143 @@
+From 3efe4df9b66d4af86363e37768ea469abb8f7bdc Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Tue, 19 Mar 2019 14:01:21 -0600
+Subject: [PATCH] unix: do not link against ___getdirentries64
+
+---
+ unix/syscall_darwin_386.go | 5 ++++-
+ unix/syscall_darwin_amd64.go | 5 ++++-
+ unix/zsyscall_darwin_386.go | 22 ----------------------
+ unix/zsyscall_darwin_386.s | 2 --
+ unix/zsyscall_darwin_amd64.go | 22 ----------------------
+ unix/zsyscall_darwin_amd64.s | 2 --
+ 6 files changed, 8 insertions(+), 50 deletions(-)
+
+diff --git a/unix/syscall_darwin_386.go b/unix/syscall_darwin_386.go
+index 489726f..900dd7c 100644
+--- a/unix/syscall_darwin_386.go
++++ b/unix/syscall_darwin_386.go
+@@ -56,8 +56,11 @@ const SYS___SYSCTL = SYS_SYSCTL
+ //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
+ //sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
+ //sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
+-//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
+ //sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64
+ //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
+ //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
+ //sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
++
++func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
++ return 0, ENOSYS
++}
+diff --git a/unix/syscall_darwin_amd64.go b/unix/syscall_darwin_amd64.go
+index 914b89b..95e245f 100644
+--- a/unix/syscall_darwin_amd64.go
++++ b/unix/syscall_darwin_amd64.go
+@@ -56,8 +56,11 @@ const SYS___SYSCTL = SYS_SYSCTL
+ //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
+ //sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
+ //sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
+-//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
+ //sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64
+ //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
+ //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
+ //sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
++
++func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
++ return 0, ENOSYS
++}
+diff --git a/unix/zsyscall_darwin_386.go b/unix/zsyscall_darwin_386.go
+index 23346dc..db4f1ea 100644
+--- a/unix/zsyscall_darwin_386.go
++++ b/unix/zsyscall_darwin_386.go
+@@ -2408,28 +2408,6 @@ func libc_fstatfs64_trampoline()
+
+ // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+- var _p0 unsafe.Pointer
+- if len(buf) > 0 {
+- _p0 = unsafe.Pointer(&buf[0])
+- } else {
+- _p0 = unsafe.Pointer(&_zero)
+- }
+- r0, _, e1 := syscall_syscall6(funcPC(libc___getdirentries64_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+- n = int(r0)
+- if e1 != 0 {
+- err = errnoErr(e1)
+- }
+- return
+-}
+-
+-func libc___getdirentries64_trampoline()
+-
+-//go:linkname libc___getdirentries64 libc___getdirentries64
+-//go:cgo_import_dynamic libc___getdirentries64 __getdirentries64 "/usr/lib/libSystem.B.dylib"
+-
+-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+-
+ func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) {
+ r0, _, e1 := syscall_syscall(funcPC(libc_getfsstat64_trampoline), uintptr(buf), uintptr(size), uintptr(flags))
+ n = int(r0)
+diff --git a/unix/zsyscall_darwin_386.s b/unix/zsyscall_darwin_386.s
+index 37b85b4..6165f70 100644
+--- a/unix/zsyscall_darwin_386.s
++++ b/unix/zsyscall_darwin_386.s
+@@ -272,8 +272,6 @@ TEXT ·libc_fstatat64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_fstatat64(SB)
+ TEXT ·libc_fstatfs64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_fstatfs64(SB)
+-TEXT ·libc___getdirentries64_trampoline(SB),NOSPLIT,$0-0
+- JMP libc___getdirentries64(SB)
+ TEXT ·libc_getfsstat64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_getfsstat64(SB)
+ TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0
+diff --git a/unix/zsyscall_darwin_amd64.go b/unix/zsyscall_darwin_amd64.go
+index c142e33..126f993 100644
+--- a/unix/zsyscall_darwin_amd64.go
++++ b/unix/zsyscall_darwin_amd64.go
+@@ -2423,28 +2423,6 @@ func libc_fstatfs64_trampoline()
+
+ // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+- var _p0 unsafe.Pointer
+- if len(buf) > 0 {
+- _p0 = unsafe.Pointer(&buf[0])
+- } else {
+- _p0 = unsafe.Pointer(&_zero)
+- }
+- r0, _, e1 := syscall_syscall6(funcPC(libc___getdirentries64_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+- n = int(r0)
+- if e1 != 0 {
+- err = errnoErr(e1)
+- }
+- return
+-}
+-
+-func libc___getdirentries64_trampoline()
+-
+-//go:linkname libc___getdirentries64 libc___getdirentries64
+-//go:cgo_import_dynamic libc___getdirentries64 __getdirentries64 "/usr/lib/libSystem.B.dylib"
+-
+-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+-
+ func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) {
+ r0, _, e1 := syscall_syscall(funcPC(libc_getfsstat64_trampoline), uintptr(buf), uintptr(size), uintptr(flags))
+ n = int(r0)
+diff --git a/unix/zsyscall_darwin_amd64.s b/unix/zsyscall_darwin_amd64.s
+index 1a39151..a19c4f5 100644
+--- a/unix/zsyscall_darwin_amd64.s
++++ b/unix/zsyscall_darwin_amd64.s
+@@ -274,8 +274,6 @@ TEXT ·libc_fstatat64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_fstatat64(SB)
+ TEXT ·libc_fstatfs64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_fstatfs64(SB)
+-TEXT ·libc___getdirentries64_trampoline(SB),NOSPLIT,$0-0
+- JMP libc___getdirentries64(SB)
+ TEXT ·libc_getfsstat64_trampoline(SB),NOSPLIT,$0-0
+ JMP libc_getfsstat64(SB)
+ TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0
+--
+2.21.0
+
diff --git a/ios/wireguard-go-bridge/wireguard.h b/ios/wireguard-go-bridge/wireguard.h
new file mode 100644
index 0000000000..e8e451b5e3
--- /dev/null
+++ b/ios/wireguard-go-bridge/wireguard.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2018-2019 WireGuard LLC. All Rights Reserved.
+ */
+
+#ifndef WIREGUARD_H
+#define WIREGUARD_H
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef struct { const char *p; size_t n; } gostring_t;
+typedef void(*logger_fn_t)(int level, const char *msg);
+extern void wgEnableRoaming(bool enabled);
+extern void wgSetLogger(logger_fn_t logger_fn);
+extern int wgTurnOn(gostring_t settings, int32_t tun_fd);
+extern void wgTurnOff(int handle);
+extern int64_t wgSetConfig(int handle, gostring_t settings);
+extern char *wgGetConfig(int handle);
+extern void wgBumpSockets(int handle);
+extern const char *wgVersion();
+
+#endif