diff --git a/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/Headers/DefaultRouteMonitor.h b/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/Headers/DefaultRouteMonitor.h
new file mode 100644
index 0000000..934f4e6
--- /dev/null
+++ b/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/Headers/DefaultRouteMonitor.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2021, Psiphon Inc.
+ * All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#import
+#import
+#import "ReachabilityProtocol.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// NetworkPathState represents the state of the network path on the device.
+@interface NetworkPathState : NSObject
+
+/// Reachability status.
+@property (nonatomic, readonly) NetworkReachability status;
+
+/// Network path state.
+@property (nonatomic, nullable, readonly) nw_path_t path;
+
+/// Default active interface available to the network path.
+@property (nonatomic, nullable, readonly) NSString* defaultActiveInterfaceName;
+
+@end
+
+/// ReachabilityChangedNotification represents the reachability state on the device.
+@interface ReachabilityChangedNotification : NSObject
+
+/// Current reachability status.
+@property (nonatomic, readonly) NetworkReachability reachabilityStatus;
+
+/// Name of current default active interface. If nil, then there is no such interface.
+@property (nonatomic, nullable, readonly) NSString* curDefaultActiveInterfaceName;
+
+/// Name of previous default active interface. If nil, then there was no default active interface previously or the previous default active
+/// interface was not capable of sending or receiving network data at the time.
+@property (nonatomic, nullable, readonly) NSString* prevDefaultActiveInterfaceName;
+
+@end
+
+/// DefaultRouteMonitor monitors changes to the default route on the device and whether that route is capable of sending and
+/// receiving network data.
+@interface DefaultRouteMonitor : NSObject
+
+/// Returns the state of the default route on the device. If nil, then there is no usable route available for sending or receiving network data.
+@property (atomic, readonly) NetworkPathState *pathState;
+
+- (instancetype)init API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+
+- (id)initWithLogger:(void (^__nonnull)(NSString *_Nonnull))logger API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+
+// Denote ReachabilityProtocol availability.
+- (BOOL)startNotifier API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+- (void)stopNotifier API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
++ (NSString*)reachabilityChangedNotification;
+- (NetworkReachability)reachabilityStatus API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+- (NSString*)reachabilityStatusDebugInfo API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/Headers/PsiphonTunnel.h b/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/Headers/PsiphonTunnel.h
index db24f58..e64231d 100644
--- a/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/Headers/PsiphonTunnel.h
+++ b/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/Headers/PsiphonTunnel.h
@@ -23,6 +23,8 @@
*/
#import "Reachability.h"
+#import "DefaultRouteMonitor.h"
+#import "ReachabilityProtocol.h"
#import "JailbreakCheck.h"
#import "PsiphonClientPlatform.h"
@@ -180,7 +182,7 @@ Called when the device's Internet connection state has changed.
This may mean that it had connectivity and now doesn't, or went from Wi-Fi to
WWAN or vice versa or VPN state changed
*/
-- (void)onInternetReachabilityChanged:(Reachability * _Nonnull)currentReachability;
+- (void)onInternetReachabilityChanged:(NetworkReachability)currentReachability;
/*!
Called when tunnel-core determines which server egress regions are available
@@ -381,7 +383,7 @@ Returns the path where the rotated notices file will be created.
disconnected state.
@return The current reachability status.
*/
-- (BOOL)getNetworkReachabilityStatus:(NetworkStatus * _Nonnull)status;
+- (BOOL)getNetworkReachabilityStatus:(NetworkReachability * _Nonnull)status;
/*!
Provides the port number of the local SOCKS proxy. Only valid when currently connected (will return 0 otherwise).
diff --git a/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/Headers/ReachabilityProtocol.h b/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/Headers/ReachabilityProtocol.h
new file mode 100644
index 0000000..e989a21
--- /dev/null
+++ b/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/Headers/ReachabilityProtocol.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021, Psiphon Inc.
+ * All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#import
+
+typedef enum : NSInteger {
+ NetworkReachabilityNotReachable = 0,
+ NetworkReachabilityReachableViaWiFi,
+ NetworkReachabilityReachableViaCellular,
+ NetworkReachabilityReachableViaWired,
+ NetworkReachabilityReachableViaLoopback,
+ NetworkReachabilityReachableViaUnknown
+} NetworkReachability;
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// ReachabilityProtocol is a protocol for monitoring the reachability of a target network destination. For example, a protocol
+/// implementation could provide reachability information for the default gateway over a specific network interface.
+/// @note The purpose of ReachabilityProtocol is to bridge the gap between Apple's old Reachability APIs and the new
+/// NWPathMonitor (iOS 12.0+) with a common interface that allows each to be used interchangeably. Using a common interface
+/// simplifies supporting older clients which cannot target NWPathMonitor until the minimum iOS target is 12.0+, at which point the
+/// code targeting the legacy Reachability APIs can be removed.
+@protocol ReachabilityProtocol
+
+/// Name of reachability notifications emitted from the default notification center. See comment for `startNotifier`.
++ (NSString*)reachabilityChangedNotification;
+
+/// Start listening for reachability changes. A notification with the name returned by `reachabilityChangedNotification` will be emitted
+/// from the default notification center until `stopNotifier` is called.
+- (BOOL)startNotifier;
+
+/// Stop listening for reachability changes.
+- (void)stopNotifier;
+
+/// Return current reachability status.
+- (NetworkReachability)reachabilityStatus;
+
+/// Return debug string which represents the current network state for logging.
+- (NSString*)reachabilityStatusDebugInfo;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/Info.plist b/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/Info.plist
index c76d894..c555112 100644
Binary files a/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/Info.plist and b/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/Info.plist differ
diff --git a/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/PsiphonTunnel b/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/PsiphonTunnel
index b3e6e84..f9b84e5 100755
Binary files a/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/PsiphonTunnel and b/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/PsiphonTunnel differ
diff --git a/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/build-git-commit.txt b/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/build-git-commit.txt
index acaa2ad..e6b961d 100644
--- a/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/build-git-commit.txt
+++ b/Frameworks/PsiphonTunnel.xcframework/ios-arm64/PsiphonTunnel.framework/build-git-commit.txt
@@ -1 +1 @@
-c9dc67dc376dcbc80ae109fea9561242974939c9
+f3d12292ed176c7170165a440d7b9b79f6a71e22
diff --git a/Frameworks/PsiphonTunnel.xcframework/ios-arm64/dSYMs/PsiphonTunnel.framework.dSYM/Contents/Resources/DWARF/PsiphonTunnel b/Frameworks/PsiphonTunnel.xcframework/ios-arm64/dSYMs/PsiphonTunnel.framework.dSYM/Contents/Resources/DWARF/PsiphonTunnel
index cb97d14..12eb990 100644
Binary files a/Frameworks/PsiphonTunnel.xcframework/ios-arm64/dSYMs/PsiphonTunnel.framework.dSYM/Contents/Resources/DWARF/PsiphonTunnel and b/Frameworks/PsiphonTunnel.xcframework/ios-arm64/dSYMs/PsiphonTunnel.framework.dSYM/Contents/Resources/DWARF/PsiphonTunnel differ
diff --git a/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/Headers/DefaultRouteMonitor.h b/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/Headers/DefaultRouteMonitor.h
new file mode 100644
index 0000000..934f4e6
--- /dev/null
+++ b/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/Headers/DefaultRouteMonitor.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2021, Psiphon Inc.
+ * All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#import
+#import
+#import "ReachabilityProtocol.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// NetworkPathState represents the state of the network path on the device.
+@interface NetworkPathState : NSObject
+
+/// Reachability status.
+@property (nonatomic, readonly) NetworkReachability status;
+
+/// Network path state.
+@property (nonatomic, nullable, readonly) nw_path_t path;
+
+/// Default active interface available to the network path.
+@property (nonatomic, nullable, readonly) NSString* defaultActiveInterfaceName;
+
+@end
+
+/// ReachabilityChangedNotification represents the reachability state on the device.
+@interface ReachabilityChangedNotification : NSObject
+
+/// Current reachability status.
+@property (nonatomic, readonly) NetworkReachability reachabilityStatus;
+
+/// Name of current default active interface. If nil, then there is no such interface.
+@property (nonatomic, nullable, readonly) NSString* curDefaultActiveInterfaceName;
+
+/// Name of previous default active interface. If nil, then there was no default active interface previously or the previous default active
+/// interface was not capable of sending or receiving network data at the time.
+@property (nonatomic, nullable, readonly) NSString* prevDefaultActiveInterfaceName;
+
+@end
+
+/// DefaultRouteMonitor monitors changes to the default route on the device and whether that route is capable of sending and
+/// receiving network data.
+@interface DefaultRouteMonitor : NSObject
+
+/// Returns the state of the default route on the device. If nil, then there is no usable route available for sending or receiving network data.
+@property (atomic, readonly) NetworkPathState *pathState;
+
+- (instancetype)init API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+
+- (id)initWithLogger:(void (^__nonnull)(NSString *_Nonnull))logger API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+
+// Denote ReachabilityProtocol availability.
+- (BOOL)startNotifier API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+- (void)stopNotifier API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
++ (NSString*)reachabilityChangedNotification;
+- (NetworkReachability)reachabilityStatus API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+- (NSString*)reachabilityStatusDebugInfo API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0));
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/Headers/PsiphonTunnel.h b/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/Headers/PsiphonTunnel.h
index db24f58..e64231d 100644
--- a/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/Headers/PsiphonTunnel.h
+++ b/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/Headers/PsiphonTunnel.h
@@ -23,6 +23,8 @@
*/
#import "Reachability.h"
+#import "DefaultRouteMonitor.h"
+#import "ReachabilityProtocol.h"
#import "JailbreakCheck.h"
#import "PsiphonClientPlatform.h"
@@ -180,7 +182,7 @@ Called when the device's Internet connection state has changed.
This may mean that it had connectivity and now doesn't, or went from Wi-Fi to
WWAN or vice versa or VPN state changed
*/
-- (void)onInternetReachabilityChanged:(Reachability * _Nonnull)currentReachability;
+- (void)onInternetReachabilityChanged:(NetworkReachability)currentReachability;
/*!
Called when tunnel-core determines which server egress regions are available
@@ -381,7 +383,7 @@ Returns the path where the rotated notices file will be created.
disconnected state.
@return The current reachability status.
*/
-- (BOOL)getNetworkReachabilityStatus:(NetworkStatus * _Nonnull)status;
+- (BOOL)getNetworkReachabilityStatus:(NetworkReachability * _Nonnull)status;
/*!
Provides the port number of the local SOCKS proxy. Only valid when currently connected (will return 0 otherwise).
diff --git a/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/Headers/ReachabilityProtocol.h b/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/Headers/ReachabilityProtocol.h
new file mode 100644
index 0000000..e989a21
--- /dev/null
+++ b/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/Headers/ReachabilityProtocol.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021, Psiphon Inc.
+ * All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#import
+
+typedef enum : NSInteger {
+ NetworkReachabilityNotReachable = 0,
+ NetworkReachabilityReachableViaWiFi,
+ NetworkReachabilityReachableViaCellular,
+ NetworkReachabilityReachableViaWired,
+ NetworkReachabilityReachableViaLoopback,
+ NetworkReachabilityReachableViaUnknown
+} NetworkReachability;
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// ReachabilityProtocol is a protocol for monitoring the reachability of a target network destination. For example, a protocol
+/// implementation could provide reachability information for the default gateway over a specific network interface.
+/// @note The purpose of ReachabilityProtocol is to bridge the gap between Apple's old Reachability APIs and the new
+/// NWPathMonitor (iOS 12.0+) with a common interface that allows each to be used interchangeably. Using a common interface
+/// simplifies supporting older clients which cannot target NWPathMonitor until the minimum iOS target is 12.0+, at which point the
+/// code targeting the legacy Reachability APIs can be removed.
+@protocol ReachabilityProtocol
+
+/// Name of reachability notifications emitted from the default notification center. See comment for `startNotifier`.
++ (NSString*)reachabilityChangedNotification;
+
+/// Start listening for reachability changes. A notification with the name returned by `reachabilityChangedNotification` will be emitted
+/// from the default notification center until `stopNotifier` is called.
+- (BOOL)startNotifier;
+
+/// Stop listening for reachability changes.
+- (void)stopNotifier;
+
+/// Return current reachability status.
+- (NetworkReachability)reachabilityStatus;
+
+/// Return debug string which represents the current network state for logging.
+- (NSString*)reachabilityStatusDebugInfo;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/Info.plist b/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/Info.plist
index 2096bac..b019b9c 100644
Binary files a/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/Info.plist and b/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/Info.plist differ
diff --git a/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/PsiphonTunnel b/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/PsiphonTunnel
index 44fd6f4..a59d079 100755
Binary files a/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/PsiphonTunnel and b/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/PsiphonTunnel differ
diff --git a/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/build-git-commit.txt b/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/build-git-commit.txt
index acaa2ad..e6b961d 100644
--- a/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/build-git-commit.txt
+++ b/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/PsiphonTunnel.framework/build-git-commit.txt
@@ -1 +1 @@
-c9dc67dc376dcbc80ae109fea9561242974939c9
+f3d12292ed176c7170165a440d7b9b79f6a71e22
diff --git a/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/dSYMs/PsiphonTunnel.framework.dSYM/Contents/Resources/DWARF/PsiphonTunnel b/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/dSYMs/PsiphonTunnel.framework.dSYM/Contents/Resources/DWARF/PsiphonTunnel
index 206187d..a6920e0 100644
Binary files a/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/dSYMs/PsiphonTunnel.framework.dSYM/Contents/Resources/DWARF/PsiphonTunnel and b/Frameworks/PsiphonTunnel.xcframework/ios-x86_64-simulator/dSYMs/PsiphonTunnel.framework.dSYM/Contents/Resources/DWARF/PsiphonTunnel differ
diff --git a/PsiphonTunnel.podspec b/PsiphonTunnel.podspec
index 13f4f65..73d4d92 100644
--- a/PsiphonTunnel.podspec
+++ b/PsiphonTunnel.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'PsiphonTunnel'
- s.version = '2.0.23'
+ s.version = '2.0.24'
s.summary = 'Psiphon tunnel iOS library'
s.homepage = 'https://psiphon3.com'
s.author = { 'Psiphon Inc' => 'info@psiphon.ca' }