From e91f74df2d95054397cd2780483f498a4c41b65c Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Mon, 17 Jul 2023 09:36:58 +0200 Subject: [PATCH 001/106] vendor: update FloatingPanel to v2.6.3 --- IVPNClient.xcodeproj/project.pbxproj | 4 +- .../FloatingPanelController+Ext.swift | 3 +- .../FloatingPanelMainLayout.swift | 163 ++++++++++++++---- .../MainScreen/MainViewController+Ext.swift | 6 +- .../MainScreen/MainViewController.swift | 3 +- 5 files changed, 136 insertions(+), 43 deletions(-) diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index d422ef218..703f5a118 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 53; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -3324,7 +3324,7 @@ repositoryURL = "https://github.com/scenee/FloatingPanel"; requirement = { kind = exactVersion; - version = 1.7.2; + version = 2.6.3; }; }; 82EC884529A12D510024CC40 /* XCRemoteSwiftPackageReference "SnapKit" */ = { diff --git a/IVPNClient/Scenes/MainScreen/ControlPanel/FloatingPanelController+Ext.swift b/IVPNClient/Scenes/MainScreen/ControlPanel/FloatingPanelController+Ext.swift index 5196bab9d..bfa23c373 100644 --- a/IVPNClient/Scenes/MainScreen/ControlPanel/FloatingPanelController+Ext.swift +++ b/IVPNClient/Scenes/MainScreen/ControlPanel/FloatingPanelController+Ext.swift @@ -27,8 +27,7 @@ import FloatingPanel extension FloatingPanelController { func setup() { - surfaceView.shadowHidden = true - surfaceView.contentInsets = .init(top: 20, left: 0, bottom: 0, right: 0) + surfaceView.contentPadding = .init(top: 20, left: 0, bottom: 0, right: 0) surfaceView.backgroundColor = UIColor.init(named: Theme.ivpnBackgroundPrimary) let contentViewController = NavigationManager.getControlPanelViewController() diff --git a/IVPNClient/Scenes/MainScreen/ControlPanel/FloatingPanelMainLayout.swift b/IVPNClient/Scenes/MainScreen/ControlPanel/FloatingPanelMainLayout.swift index 01715b4cd..8272f954d 100644 --- a/IVPNClient/Scenes/MainScreen/ControlPanel/FloatingPanelMainLayout.swift +++ b/IVPNClient/Scenes/MainScreen/ControlPanel/FloatingPanelMainLayout.swift @@ -26,9 +26,9 @@ import FloatingPanel class FloatingPanelMainLayout: FloatingPanelLayout { - // MARK: - Override public properties - + var position: FloatingPanelPosition { .bottom } - public var initialPosition: FloatingPanelPosition { + var initialState: FloatingPanelState { if UIDevice.current.userInterfaceIdiom == .pad && UIWindow.isLandscape && !UIApplication.shared.isSplitOrSlideOver { return .full } @@ -36,12 +36,11 @@ class FloatingPanelMainLayout: FloatingPanelLayout { return .half } - public var supportedPositions: Set { - if UIDevice.current.userInterfaceIdiom == .pad && UIWindow.isLandscape && !UIApplication.shared.isSplitOrSlideOver { - return [.full] - } - - return [.full, .half] + var anchors: [FloatingPanelState: FloatingPanelLayoutAnchoring] { + return [ + .full: FloatingPanelLayoutAnchor(absoluteInset: 0, edge: .top, referenceGuide: .safeArea), + .half: FloatingPanelLayoutAnchor(absoluteInset: halfHeight, edge: .bottom, referenceGuide: .safeArea) + ] } // MARK: - Private properties - @@ -60,37 +59,19 @@ class FloatingPanelMainLayout: FloatingPanelLayout { return 230 - bottomSafeArea } - // MARK: - Override public methods - - - public func insetFor(position: FloatingPanelPosition) -> CGFloat? { - if UIDevice.current.userInterfaceIdiom == .pad && UIWindow.isLandscape && !UIApplication.shared.isSplitOrSlideOver { - switch position { - case .full: - return -20 - default: - return nil - } - } - - switch position { - case .full: - return 10 - case .half: - return halfHeight - default: - return nil - } - } - public func prepareLayout(surfaceView: UIView, in view: UIView) -> [NSLayoutConstraint] { - if let surfaceView = surfaceView as? FloatingPanelSurfaceView { + if let surfaceView = surfaceView as? SurfaceView { + let appearance = SurfaceAppearance() + if UIDevice.current.userInterfaceIdiom == .pad && UIWindow.isLandscape && !UIApplication.shared.isSplitOrSlideOver { surfaceView.grabberHandle.isHidden = true - surfaceView.cornerRadius = 0 + appearance.cornerRadius = 0 } else { surfaceView.grabberHandle.isHidden = false - surfaceView.cornerRadius = 15 + appearance.cornerRadius = 15 } + + surfaceView.appearance = appearance } if UIDevice.current.userInterfaceIdiom == .pad && UIWindow.isLandscape && !UIApplication.shared.isSplitOrSlideOver { @@ -113,8 +94,8 @@ class FloatingPanelMainLayout: FloatingPanelLayout { ] } - public func backdropAlphaFor(position: FloatingPanelPosition) -> CGFloat { - if position == .full && (UIDevice.current.userInterfaceIdiom == .phone || UIWindow.isPortrait) { + public func backdropAlpha(for state: FloatingPanelState) -> CGFloat { + if state == .full && (UIDevice.current.userInterfaceIdiom == .phone || UIWindow.isPortrait) { return 0.3 } @@ -122,3 +103,115 @@ class FloatingPanelMainLayout: FloatingPanelLayout { } } + +class MainFloatingPanelBehavior: FloatingPanelBehavior { + + func allowsRubberBanding(for edge: UIRectEdge) -> Bool { + return false + } + + func shouldProjectMomentum(_ fpc: FloatingPanelController, to proposedTargetPosition: FloatingPanelState) -> Bool { + return false + } + +} + +//class FloatingPanelMainLayout: FloatingPanelLayout { +// +// // MARK: - Override public properties - +// +// public var initialPosition: FloatingPanelPosition { +// if UIDevice.current.userInterfaceIdiom == .pad && UIWindow.isLandscape && !UIApplication.shared.isSplitOrSlideOver { +// return .full +// } +// +// return .half +// } +// +// public var supportedPositions: Set { +// if UIDevice.current.userInterfaceIdiom == .pad && UIWindow.isLandscape && !UIApplication.shared.isSplitOrSlideOver { +// return [.full] +// } +// +// return [.full, .half] +// } +// +// // MARK: - Private properties - +// +// private let bottomSafeArea = UIWindow.keyWindow?.safeAreaInsets.bottom ?? 0 +// +// private var halfHeight: CGFloat { +// if Application.shared.settings.connectionProtocol.tunnelType() != .ipsec && UserDefaults.shared.isMultiHop { +// return 359 - bottomSafeArea +// } +// +// if Application.shared.settings.connectionProtocol.tunnelType() != .ipsec { +// return 274 - bottomSafeArea +// } +// +// return 230 - bottomSafeArea +// } +// +// // MARK: - Override public methods - +// +// public func insetFor(position: FloatingPanelPosition) -> CGFloat? { +// if UIDevice.current.userInterfaceIdiom == .pad && UIWindow.isLandscape && !UIApplication.shared.isSplitOrSlideOver { +// switch position { +// case .full: +// return -20 +// default: +// return nil +// } +// } +// +// switch position { +// case .full: +// return 10 +// case .half: +// return halfHeight +// default: +// return nil +// } +// } +// +// public func prepareLayout(surfaceView: UIView, in view: UIView) -> [NSLayoutConstraint] { +// if let surfaceView = surfaceView as? FloatingPanelSurfaceView { +// if UIDevice.current.userInterfaceIdiom == .pad && UIWindow.isLandscape && !UIApplication.shared.isSplitOrSlideOver { +// surfaceView.grabberHandle.isHidden = true +// surfaceView.cornerRadius = 0 +// } else { +// surfaceView.grabberHandle.isHidden = false +// surfaceView.cornerRadius = 15 +// } +// } +// +// if UIDevice.current.userInterfaceIdiom == .pad && UIWindow.isLandscape && !UIApplication.shared.isSplitOrSlideOver { +// return [ +// surfaceView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor, constant: 0), +// surfaceView.widthAnchor.constraint(equalToConstant: 375) +// ] +// } +// +// if UIDevice.current.userInterfaceIdiom == .pad && UIWindow.isPortrait && !UIApplication.shared.isSplitOrSlideOver { +// return [ +// surfaceView.widthAnchor.constraint(equalToConstant: 520), +// surfaceView.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor) +// ] +// } +// +// return [ +// surfaceView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor, constant: 0), +// surfaceView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor, constant: 0) +// ] +// } +// +// public func backdropAlphaFor(position: FloatingPanelPosition) -> CGFloat { +// if position == .full && (UIDevice.current.userInterfaceIdiom == .phone || UIWindow.isPortrait) { +// return 0.3 +// } +// +// return 0 +// } +// +//} + diff --git a/IVPNClient/Scenes/MainScreen/MainViewController+Ext.swift b/IVPNClient/Scenes/MainScreen/MainViewController+Ext.swift index a6f43f1ec..ac69a0dd3 100644 --- a/IVPNClient/Scenes/MainScreen/MainViewController+Ext.swift +++ b/IVPNClient/Scenes/MainScreen/MainViewController+Ext.swift @@ -28,7 +28,7 @@ import FloatingPanel extension MainViewController: FloatingPanelControllerDelegate { - func floatingPanel(_ vc: FloatingPanelController, layoutFor newCollection: UITraitCollection) -> FloatingPanelLayout? { + func floatingPanel(_ vc: FloatingPanelController, layoutFor newCollection: UITraitCollection) -> FloatingPanelLayout { updateAccessibilityLabel(vc: vc) return FloatingPanelMainLayout() @@ -44,7 +44,7 @@ extension MainViewController: FloatingPanelControllerDelegate { func updateAccessibilityLabel(vc: FloatingPanelController) { if let controlPanelViewController = floatingPanel.contentViewController, UIDevice.current.userInterfaceIdiom != .pad { - if vc.position == .full { + if vc.state == .full { controlPanelViewController.view.accessibilityLabel = "Swipe down to collapse control panel" } else { controlPanelViewController.view.accessibilityLabel = "Swipe up to expan control panel" @@ -59,7 +59,7 @@ extension MainViewController: FloatingPanelControllerDelegate { extension MainViewController: UIAdaptivePresentationControllerDelegate { func presentationControllerWillDismiss(_ presentationController: UIPresentationController) { - floatingPanel.updateLayout() + floatingPanel.invalidateLayout() NotificationCenter.default.post(name: Notification.Name.UpdateControlPanel, object: nil) } diff --git a/IVPNClient/Scenes/MainScreen/MainViewController.swift b/IVPNClient/Scenes/MainScreen/MainViewController.swift index 0539f5e6b..c0c83d0e5 100644 --- a/IVPNClient/Scenes/MainScreen/MainViewController.swift +++ b/IVPNClient/Scenes/MainScreen/MainViewController.swift @@ -202,7 +202,7 @@ class MainViewController: UIViewController { // MARK: - Private methods - @objc private func updateFloatingPanelLayout() { - floatingPanel.updateLayout() + floatingPanel.invalidateLayout() mainView.setupView(animated: false) } @@ -237,6 +237,7 @@ class MainViewController: UIViewController { floatingPanel.delegate = self floatingPanel.addPanel(toParent: self) floatingPanel.show(animated: true) + floatingPanel.behavior = MainFloatingPanelBehavior() } private func startAPIUpdate() { From c9ba3571621e53729dd37dbe173277bdcb95e59d Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Mon, 17 Jul 2023 17:31:02 +0200 Subject: [PATCH 002/106] vendor: update FloatingPanelMainLayout.swift --- .../MainScreen/ControlPanel/FloatingPanelMainLayout.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/IVPNClient/Scenes/MainScreen/ControlPanel/FloatingPanelMainLayout.swift b/IVPNClient/Scenes/MainScreen/ControlPanel/FloatingPanelMainLayout.swift index 8272f954d..eb7680fb8 100644 --- a/IVPNClient/Scenes/MainScreen/ControlPanel/FloatingPanelMainLayout.swift +++ b/IVPNClient/Scenes/MainScreen/ControlPanel/FloatingPanelMainLayout.swift @@ -62,6 +62,10 @@ class FloatingPanelMainLayout: FloatingPanelLayout { public func prepareLayout(surfaceView: UIView, in view: UIView) -> [NSLayoutConstraint] { if let surfaceView = surfaceView as? SurfaceView { let appearance = SurfaceAppearance() + let shadow = SurfaceAppearance.Shadow() + shadow.color = .clear + appearance.shadows = [shadow] + appearance.backgroundColor = UIColor.init(named: Theme.ivpnBackgroundPrimary) if UIDevice.current.userInterfaceIdiom == .pad && UIWindow.isLandscape && !UIApplication.shared.isSplitOrSlideOver { surfaceView.grabberHandle.isHidden = true From de5e5490f1b3f8292c39bcfef675f65b5b394b0c Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Mon, 31 Jul 2023 11:41:05 +0200 Subject: [PATCH 003/106] feat(v2ray): add v2ray-core submodule --- .gitmodules | 3 +++ vendor/v2ray-core | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 vendor/v2ray-core diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..86e1c16b4 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "vendor/v2ray-core"] + path = vendor/v2ray-core + url = https://github.com/v2ray/v2ray-core diff --git a/vendor/v2ray-core b/vendor/v2ray-core new file mode 160000 index 000000000..d80440f3d --- /dev/null +++ b/vendor/v2ray-core @@ -0,0 +1 @@ +Subproject commit d80440f3d57b45c829dbf513306f7adf9a0f3f76 From 06d798c75b23111f3aa943e190fbfa1eeabf178f Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Mon, 31 Jul 2023 12:09:00 +0200 Subject: [PATCH 004/106] feat(v2ray): create build.sh --- .gitignore | 5 ++++- build.sh | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100755 build.sh diff --git a/.gitignore b/.gitignore index ab0ae2197..22d1350d4 100644 --- a/.gitignore +++ b/.gitignore @@ -69,4 +69,7 @@ OpenVPNConf.swift # Fastlane fastlane/test_output fastlane/report.xml -fastlane/Appfile \ No newline at end of file +fastlane/Appfile + +# Frameworks +Frameworks diff --git a/build.sh b/build.sh new file mode 100755 index 000000000..d69656151 --- /dev/null +++ b/build.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Exit immediately if a command exits with a non-zero status. +set -e + +echo "=> ⬇️ Clone V2Ray sources.." +git submodule update --init + +echo "=> ⬇️ Get gomobile.." +cd vendor/v2ray-core +PATH=$PATH:~/go/bin +go get golang.org/x/mobile/cmd/gomobile + +echo "=> 🍏 Build iOS library.." +gomobile bind --target=ios -o ../../Frameworks/V2Ray.xcframework +echo "=> ✅ iOS build completed" From d5fa1c4347204afbce652142768fa3c20128a6df Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Fri, 4 Aug 2023 10:42:50 +0200 Subject: [PATCH 005/106] feat(v2ray): link V2Ray.xcframework --- IVPNClient.xcodeproj/project.pbxproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index 0e58ec935..2c601faa3 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -44,6 +44,9 @@ 82152C9929F14B4C007FCECC /* KeyChain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82152C9829F14B4C007FCECC /* KeyChain.swift */; }; 82152C9B29F17568007FCECC /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 82152C9A29F17568007FCECC /* KeychainAccess */; }; 821AFA1323602B71001EF617 /* SettingsScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821AFA1223602B71001EF617 /* SettingsScreenTests.swift */; }; + 821BB5C02A7CF0C9005D9D64 /* V2Ray.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 821BB5BF2A7CF0C9005D9D64 /* V2Ray.xcframework */; }; + 821BB5C12A7CF0C9005D9D64 /* V2Ray.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 821BB5BF2A7CF0C9005D9D64 /* V2Ray.xcframework */; }; + 821BB5C22A7CF0C9005D9D64 /* V2Ray.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 821BB5BF2A7CF0C9005D9D64 /* V2Ray.xcframework */; }; 821BDE02224A6EC700F592BF /* AppKeyManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821BDE01224A6EC700F592BF /* AppKeyManagerTests.swift */; }; 821CA2D7287C5AB20067F70D /* PortViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821CA2D6287C5AB20067F70D /* PortViewController.swift */; }; 821CA2DB288039670067F70D /* PortTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821CA2DA288039670067F70D /* PortTableViewCell.swift */; }; @@ -468,6 +471,7 @@ 821429BA22FC36100056B8FF /* ApiRequestDI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiRequestDI.swift; sourceTree = ""; }; 82152C9829F14B4C007FCECC /* KeyChain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyChain.swift; sourceTree = ""; }; 821AFA1223602B71001EF617 /* SettingsScreenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreenTests.swift; sourceTree = ""; }; + 821BB5BF2A7CF0C9005D9D64 /* V2Ray.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = V2Ray.xcframework; path = Frameworks/V2Ray.xcframework; sourceTree = ""; }; 821BDE01224A6EC700F592BF /* AppKeyManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppKeyManagerTests.swift; sourceTree = ""; }; 821CA2D6287C5AB20067F70D /* PortViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortViewController.swift; sourceTree = ""; }; 821CA2DA288039670067F70D /* PortTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortTableViewCell.swift; sourceTree = ""; }; @@ -756,6 +760,7 @@ buildActionMask = 2147483647; files = ( 82B6052F21708575004B40E6 /* NetworkExtension.framework in Frameworks */, + 821BB5C22A7CF0C9005D9D64 /* V2Ray.xcframework in Frameworks */, 82BF79622A2F8DDC00061972 /* liboqs.a in Frameworks */, 824B86E126D42A5700D0101A /* WireGuardKit in Frameworks */, 829F5FCB29A13CF2009E1AD3 /* KeychainAccess in Frameworks */, @@ -784,6 +789,7 @@ buildActionMask = 2147483647; files = ( 9CF7E35A20F7A86E008E0EC5 /* NetworkExtension.framework in Frameworks */, + 821BB5C12A7CF0C9005D9D64 /* V2Ray.xcframework in Frameworks */, 829407C12A3DCE9200E6B68E /* liboqs.a in Frameworks */, 82968A34298A970500077E0A /* TunnelKitOpenVPNAppExtension in Frameworks */, 829F5FC929A13CEA009E1AD3 /* KeychainAccess in Frameworks */, @@ -795,6 +801,7 @@ buildActionMask = 2147483647; files = ( 82D598C621A6A5C7000FABDE /* SystemConfiguration.framework in Frameworks */, + 821BB5C02A7CF0C9005D9D64 /* V2Ray.xcframework in Frameworks */, 9CB2CE311DAF9227007A4D2D /* CoreData.framework in Frameworks */, 9C6942251DD0CBF800F9A801 /* NetworkExtension.framework in Frameworks */, 82486FAD2A277058009B53F4 /* liboqs.a in Frameworks */, @@ -817,6 +824,7 @@ 584496306C3B9383149618CE /* Frameworks */ = { isa = PBXGroup; children = ( + 821BB5BF2A7CF0C9005D9D64 /* V2Ray.xcframework */, 8294BC8D22A126C900328932 /* TunnelKit.framework */, 8294BC8B22A10F4100328932 /* TunnelKit.framework */, 824F56072233FE6F00BCDD5C /* libwg-go.a */, From d164004f6517306342c72672f03aa75520f3c118 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Fri, 4 Aug 2023 10:55:33 +0200 Subject: [PATCH 006/106] feat(v2ray): create Decodable+Ext.swift --- IVPNClient.xcodeproj/project.pbxproj | 16 ++++++++ .../Utilities/Extensions/Decodable+Ext.swift | 37 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 IVPNClient/Utilities/Extensions/Decodable+Ext.swift diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index 2c601faa3..a108931b6 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -65,6 +65,9 @@ 822919712182EB1C00978BBA /* String+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8229196D2182EB1B00978BBA /* String+Ext.swift */; }; 822920A02480FA3600476FC1 /* ServersSort.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8229209F2480FA3600476FC1 /* ServersSort.swift */; }; 822B85D921B941A200715691 /* NotificationName+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 822B85D821B941A200715691 /* NotificationName+Ext.swift */; }; + 822BC68A2A7CF3A700C733DF /* Decodable+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 822BC6892A7CF3A700C733DF /* Decodable+Ext.swift */; }; + 822BC68B2A7CF3A700C733DF /* Decodable+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 822BC6892A7CF3A700C733DF /* Decodable+Ext.swift */; }; + 822BC68C2A7CF3A700C733DF /* Decodable+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 822BC6892A7CF3A700C733DF /* Decodable+Ext.swift */; }; 822EE96C215CE0E300BE77F6 /* UserDefaults+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 825A43FC215CCFE70076131F /* UserDefaults+Ext.swift */; }; 8232FBF42240DE19006B81D2 /* ErrorResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8232FBF32240DE19006B81D2 /* ErrorResult.swift */; }; 8232FBF62240E40F006B81D2 /* Error+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8232FBF52240E40F006B81D2 /* Error+Ext.swift */; }; @@ -486,6 +489,7 @@ 8229196D2182EB1B00978BBA /* String+Ext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Ext.swift"; sourceTree = ""; }; 8229209F2480FA3600476FC1 /* ServersSort.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServersSort.swift; sourceTree = ""; }; 822B85D821B941A200715691 /* NotificationName+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NotificationName+Ext.swift"; sourceTree = ""; }; + 822BC6892A7CF3A700C733DF /* Decodable+Ext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Decodable+Ext.swift"; sourceTree = ""; }; 8232FBF32240DE19006B81D2 /* ErrorResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorResult.swift; sourceTree = ""; }; 8232FBF52240E40F006B81D2 /* Error+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Error+Ext.swift"; sourceTree = ""; }; 82351FC9241FA16600E6E0FD /* InfoAlertViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoAlertViewModelTests.swift; sourceTree = ""; }; @@ -912,6 +916,13 @@ path = MainScreen; sourceTree = ""; }; + 821BB5C32A7CF198005D9D64 /* V2Ray */ = { + isa = PBXGroup; + children = ( + ); + path = V2Ray; + sourceTree = ""; + }; 821F1C7C21FF541800107311 /* ViewModels */ = { isa = PBXGroup; children = ( @@ -989,6 +1000,7 @@ children = ( 82A208B821BAA66800C9AD44 /* CoreData */, 8292E1A52174C0CE00123538 /* WireGuard */, + 821BB5C32A7CF198005D9D64 /* V2Ray */, 9C3324F21DB37724003885C3 /* VPNServer.swift */, 9CB2CE401DB2594A007A4D2D /* VPNServerList.swift */, 82C9739F217DFA9C00CE06D4 /* Host.swift */, @@ -1128,6 +1140,7 @@ 82E5449124EE584E006DEF8D /* UIImageView+Ext.swift */, 82CE598F25ED3C7A0078099D /* URL+Ext.swift */, 82B329CA29F7C9F400F3ED9B /* UIWindow+Ext.swift */, + 822BC6892A7CF3A700C733DF /* Decodable+Ext.swift */, ); path = Extensions; sourceTree = ""; @@ -2047,6 +2060,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 822BC68C2A7CF3A700C733DF /* Decodable+Ext.swift in Sources */, 82E7169A2181E96F00D6B7C2 /* OpenVPNProtocol.swift in Sources */, 8205352A2302BEA3007BDD58 /* Array+Ext.swift in Sources */, 82E716882181E8E100D6B7C2 /* ProviderConfigurationKeys.swift in Sources */, @@ -2157,6 +2171,7 @@ 8223C54F22EAEC7000CD283D /* Session.swift in Sources */, 82ED17432A12596E00E7926D /* AddressType.swift in Sources */, 826C56D322FD551800D2B76A /* ServiceStatus.swift in Sources */, + 822BC68B2A7CF3A700C733DF /* Decodable+Ext.swift in Sources */, 82E716932181E90500D6B7C2 /* ConnectionSettings.swift in Sources */, 82ED17592A1262F800E7926D /* Data+Ext.swift in Sources */, 823FFB082338E09900F91A5D /* Capability.swift in Sources */, @@ -2223,6 +2238,7 @@ 827694F3263C04C40058B4DC /* LoginConfirmation.swift in Sources */, 82774855237596DF0061BD46 /* OpenVPNConf.swift in Sources */, 82589A2B21FB5A580009CC6C /* UIImage+Ext.swift in Sources */, + 822BC68A2A7CF3A700C733DF /* Decodable+Ext.swift in Sources */, 829D2C8221664D5E004FA2B3 /* NSMutableAttributedString+Ext.swift in Sources */, 820535282302B9D7007BDD58 /* APIAccessManager.swift in Sources */, 829DF27E2497949A000DC2DB /* SelectPlanView.swift in Sources */, diff --git a/IVPNClient/Utilities/Extensions/Decodable+Ext.swift b/IVPNClient/Utilities/Extensions/Decodable+Ext.swift new file mode 100644 index 000000000..28d5cd91e --- /dev/null +++ b/IVPNClient/Utilities/Extensions/Decodable+Ext.swift @@ -0,0 +1,37 @@ +// +// Decodable+Ext.swift +// IVPN iOS app +// https://github.com/ivpn/ios-app +// +// Created by Juraj Hilje on 2023-08-04. +// Copyright (c) 2023 Privatus Limited. +// +// This file is part of the IVPN iOS app. +// +// The IVPN iOS app 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. +// +// The IVPN iOS app 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 the IVPN iOS app. If not, see . +// + +import Foundation + +extension Decodable { + + static func parse(fromJsonFile: String) -> Self? { + guard let url = Bundle.main.url(forResource: fromJsonFile, withExtension: "json"), + let data = try? Data(contentsOf: url), + let output = try? JSONDecoder().decode(self, from: data) else { + return nil + } + return output + } + +} From 052c9d9a79a3b8178ee6bd396aec654ad5684a90 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Fri, 4 Aug 2023 13:18:22 +0200 Subject: [PATCH 007/106] feat(v2ray): create V2RayConfig.swift --- IVPNClient.xcodeproj/project.pbxproj | 8 + IVPNClient/Models/V2Ray/V2RayConfig.swift | 633 ++++++++++++++++++++++ 2 files changed, 641 insertions(+) create mode 100644 IVPNClient/Models/V2Ray/V2RayConfig.swift diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index a108931b6..05632bc54 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -91,6 +91,9 @@ 824777E721A6BC3A001EEFAF /* Network+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824777E521A6BC3A001EEFAF /* Network+CoreDataClass.swift */; }; 824777EA21A6BC3A001EEFAF /* Network+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824777E621A6BC3A001EEFAF /* Network+CoreDataProperties.swift */; }; 8247A5ED215D037600E8D680 /* UserDefaults+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 825A43FC215CCFE70076131F /* UserDefaults+Ext.swift */; }; + 8247C0602A7CF54300A7C02F /* V2RayConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8247C05F2A7CF54300A7C02F /* V2RayConfig.swift */; }; + 8247C0612A7CF54300A7C02F /* V2RayConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8247C05F2A7CF54300A7C02F /* V2RayConfig.swift */; }; + 8247C0622A7CF54300A7C02F /* V2RayConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8247C05F2A7CF54300A7C02F /* V2RayConfig.swift */; }; 8247E1DA22686217006C0C08 /* IAPManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8247E1D922686217006C0C08 /* IAPManager.swift */; }; 8247E1DE22687C28006C0C08 /* ProductIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8247E1DD22687C28006C0C08 /* ProductIdentifier.swift */; }; 82486FAD2A277058009B53F4 /* liboqs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 82486FAC2A277058009B53F4 /* liboqs.a */; }; @@ -508,6 +511,7 @@ 8243587025DBB73E005FDEBB /* SecureDNS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureDNS.swift; sourceTree = ""; }; 824777E521A6BC3A001EEFAF /* Network+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Network+CoreDataClass.swift"; sourceTree = ""; }; 824777E621A6BC3A001EEFAF /* Network+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Network+CoreDataProperties.swift"; sourceTree = ""; }; + 8247C05F2A7CF54300A7C02F /* V2RayConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = V2RayConfig.swift; sourceTree = ""; }; 8247E1D922686217006C0C08 /* IAPManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IAPManager.swift; sourceTree = ""; }; 8247E1DD22687C28006C0C08 /* ProductIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductIdentifier.swift; sourceTree = ""; }; 82486FAC2A277058009B53F4 /* liboqs.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = liboqs.a; sourceTree = ""; }; @@ -919,6 +923,7 @@ 821BB5C32A7CF198005D9D64 /* V2Ray */ = { isa = PBXGroup; children = ( + 8247C05F2A7CF54300A7C02F /* V2RayConfig.swift */, ); path = V2Ray; sourceTree = ""; @@ -2064,6 +2069,7 @@ 82E7169A2181E96F00D6B7C2 /* OpenVPNProtocol.swift in Sources */, 8205352A2302BEA3007BDD58 /* Array+Ext.swift in Sources */, 82E716882181E8E100D6B7C2 /* ProviderConfigurationKeys.swift in Sources */, + 8247C0622A7CF54300A7C02F /* V2RayConfig.swift in Sources */, 82F638C5217DA89000410318 /* AddressType.swift in Sources */, 82EEB6DB25F961BC00915837 /* URL+Ext.swift in Sources */, 822919712182EB1C00978BBA /* String+Ext.swift in Sources */, @@ -2186,6 +2192,7 @@ 829407C02A3DCC5500E6B68E /* KemHelper.swift in Sources */, 82ED17472A125A4700E7926D /* APIPublicKeyPin.swift in Sources */, 827123172A3C758100882336 /* AppKeyManager.swift in Sources */, + 8247C0612A7CF54300A7C02F /* V2RayConfig.swift in Sources */, 82ED17552A1262BA00E7926D /* Interface.swift in Sources */, 82E716812181E8AF00D6B7C2 /* TunnelType.swift in Sources */, 82A208C121BAAC6C00C9AD44 /* Config.swift in Sources */, @@ -2285,6 +2292,7 @@ 9CB2CE1F1DAA5258007A4D2D /* Authentication.swift in Sources */, 82DAB37B2457013900302F4C /* Service.swift in Sources */, 825ECB2C2A5582570032E986 /* AntiTrackerDns.swift in Sources */, + 8247C0602A7CF54300A7C02F /* V2RayConfig.swift in Sources */, 82C2E5DF21620FF100C5A09F /* UIDevice+Ext.swift in Sources */, 8208525823FD5EB20008C112 /* MainViewController.swift in Sources */, 825E836325A4834200938240 /* APIPublicKeyPin.swift in Sources */, diff --git a/IVPNClient/Models/V2Ray/V2RayConfig.swift b/IVPNClient/Models/V2Ray/V2RayConfig.swift new file mode 100644 index 000000000..8b60fa508 --- /dev/null +++ b/IVPNClient/Models/V2Ray/V2RayConfig.swift @@ -0,0 +1,633 @@ +// +// V2RayConfig.swift +// IVPN iOS app +// https://github.com/ivpn/ios-app +// +// Created by Juraj Hilje on 2023-08-04. +// Copyright (c) 2023 Privatus Limited. +// +// This file is part of the IVPN iOS app. +// +// The IVPN iOS app 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. +// +// The IVPN iOS app 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 the IVPN iOS app. If not, see . +// + +import Foundation + +struct V2RayConfig: Codable { + var log: Log? + var api: Api? + var dns: Dns? + var stats: Stats? + var routing: Routing? + var policy: Policy? + var inbounds: [Inbound]? + var outbounds: [Outbound]? + var transport: Transport? +} + +extension V2RayConfig { + + // MARK: - Log + + struct Log: Codable { + var loglevel: Level = .info + var error: String = "" + var access: String = "" + + enum Level: String, Codable { + case debug + case info + case warning + case error + case none + } + } + + // MARK: - API + + struct Api: Codable {} + + // MARK: - DNS + + struct Dns: Codable { + var servers = [String]() + } + + // MARK: - Stats + + struct Stats: Codable {} + + // MARK: - Routing + + struct Routing: Codable { + var strategy: String = "rules" + var settings: Setting = Setting() + + struct Setting: Codable { + enum domainStrategy: String, Codable { + case AsIs + case IPIfNonMatch + case IPOnDemand + } + + var domainStrategy: domainStrategy = .IPIfNonMatch + var rules: [Rule] = [Rule()] + + struct Rule: Codable { + var type: String? = "field" + var domain: [String]? = [] + var ip: [String]? = [] + var port: String? + var network: String? + var source: [String]? + var user: [String]? + var inboundTag: [String]? + var `protocol`: [String]? // ["http", "tls", "bittorrent"] + var outboundTag: String? = "direct" + } + } + } + + // MARK: - Policy + + struct Policy: Codable {} + + // MARK: - Inbound + + struct Inbound: Codable { + var port: String = "" + var listen: String = "" + var `protocol`: Protocol = .socks + var tag: String? = nil + var streamSettings: StreamSettings? = nil + var sniffing: Sniffing? = nil + var allocate: Allocate? = nil + + var settingHttp: Http = Http() + var settingSocks: Socks = Socks() + var settingShadowsocks: Shadowsocks? = nil + var settingVMess: VMess? = nil + + enum CodingKeys: String, CodingKey { + case port + case listen + case `protocol` + case tag + case streamSettings + case sniffing + case settings + } + + enum `Protocol`: String, Codable { + case http + case shadowsocks + case socks + case vmess + } + + struct Allocate: Codable { + var strategy: strategy = .always // always or random + var refresh: Int = 2 // val is 2-5 where strategy = random + var concurrency: Int = 3 // suggest 3, min 1 + + enum strategy: String, Codable { + case always + case random + } + } + + struct Sniffing: Codable { + var enabled: Bool = false + var destOverride: [dest] = [.tls, .http] + + enum dest: String, Codable { + case tls + case http + } + } + + struct Http: Codable { + var timeout: Int = 360 + var allowTransparent: Bool? + var userLevel: Int? + var accounts: [Account]? + + struct Account: Codable { + var user: String? + var pass: String? + } + } + + struct Shadowsocks: Codable { + var email, method, password: String? + var udp: Bool = false + var level: Int = 0 + var ota: Bool = true + var network: String = "tcp" // "tcp" | "udp" | "tcp,udp" + } + + struct Socks: Codable { + var auth: String = "noauth" // noauth | password + var accounts: [Account]? + var udp: Bool = true + var ip: String? + var timeout: Int = 360 + var userLevel: Int? + + struct Account: Codable { + var user: String? + var pass: String? + } + } + + struct VMess: Codable { + var clients: [Client]? + var `default`: Default? = Default() + var detour:Detour? + var disableInsecureEncryption: Bool = false + + struct Client: Codable { + var id: String? + var level: Int = 0 + var alterId: Int = 64 + var email: String? + } + + struct Detour: Codable { + var to: String? + } + + struct Default: Codable { + var level: Int = 0 + var alterId: Int = 64 + } + } + + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + port = try container.decode(String.self, forKey: .port) + listen = try container.decode(String.self, forKey: .listen) + `protocol` = try container.decode(Protocol.self, forKey: .`protocol`) + + tag = container.contains(.tag) ? try container.decode(String.self, forKey: .tag) : nil + streamSettings = container.contains(.streamSettings) ? try container.decode(StreamSettings.self, forKey: CodingKeys.streamSettings) : nil + sniffing = container.contains(.sniffing) ? try container.decode(Sniffing.self, forKey: CodingKeys.sniffing) : nil + + switch `protocol` { + case .http: + settingHttp = try container.decode(Http.self, forKey: CodingKeys.settings) + case .shadowsocks: + settingShadowsocks = try container.decode(Shadowsocks.self, forKey: CodingKeys.settings) + case .socks: + settingSocks = try container.decode(Socks.self, forKey: CodingKeys.settings) + case .vmess: + settingVMess = try container.decode(VMess.self, forKey: CodingKeys.settings) + } + } + + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(port, forKey: .port) + try container.encode(listen, forKey: .listen) + try container.encode(`protocol`, forKey: .`protocol`) + + tag == nil ? nil : try container.encode(tag, forKey: .tag) + streamSettings == nil ? nil : try container.encode(streamSettings, forKey: .streamSettings) + sniffing == nil ? nil : try container.encode(sniffing, forKey: .sniffing) + + switch `protocol` { + case .http: + try container.encode(self.settingHttp, forKey: .settings) + case .shadowsocks: + try container.encode(self.settingShadowsocks, forKey: .settings) + case .socks: + try container.encode(self.settingSocks, forKey: .settings) + case .vmess: + try container.encode(self.settingVMess, forKey: .settings) + } + } + } + + // MARK: - Outbound + + struct Outbound: Codable { + var `protocol`: Protocol = .freedom + var sendThrough: String? = nil + var tag: String? = nil + var streamSettings: StreamSettings? = nil + var proxySettings: Settings? = nil + var mux: Mux? = nil + + var settingBlackhole: Blackhole? = nil + var settingFreedom: Freedom? = nil + var settingShadowsocks: Shadowsocks? = nil + var settingSocks: Socks? = nil + var settingVMess: VMess? = nil + var settingDns: Dns? = nil + + enum CodingKeys: String, CodingKey { + case sendThrough + case `protocol` + case tag + case streamSettings + case proxySettings + case mux + case settings + } + + struct Settings: Codable { + var Tag: String? + } + + enum `Protocol`: String, Codable { + case blackhole + case freedom + case shadowsocks + case socks + case vmess + case dns + } + + struct Mux: Codable { + var enabled: Bool = false + var concurrency: Int? = 8 + } + + struct Blackhole: Codable { + var response: Response = Response() + + struct Response: Codable { + var type: String? = "none" // none | http + } + } + + struct Freedom: Codable { + var domainStrategy: String = "AsIs" // UseIP | AsIs + var redirect: String? + var userLevel: Int = 0 + } + + struct Shadowsocks: Codable { + var servers: [Server] = [Server()] + + struct Server: Codable { + var email: String = "" + var address: String = "" + var port: Int = 0 + var method: Method = .aes256cfb + var password: String = "" + var ota: Bool = false + var level: Int = 0 + } + + enum Method: String, Codable { + case aes256cfb = "aes-256-cfb" + case aes128cfb = "aes-128-cfb" + case chacha20 = "chacha20" + case chacha20ietf = "chacha20-ietf" + case aes256gcm = "aes-256-gcm" + case aes128gcm = "aes-128-gcm" + case chacha20poly1305 = "chacha20-poly1305" + case chacha20ietfpoly1305 = "chacha20-ietf-poly1305" + } + } + + struct Socks: Codable { + var address: String = "" + var port: String = "" + var users: [User] = [User()] + + struct User: Codable { + var user: String = "" + var pass: String = "" + var level: Int = 0 + } + } + + struct VMess: Codable { + var vnext: [Item] = [Item()] + + struct Item: Codable { + var address: String = "" + var port: Int = 443 + var users: [User] = [User()] + + struct User: Codable { + var id: String = "" + var alterId: Int = 64 // 0-65535 + var level: Int? = 0 + var security: Security = .auto + + enum Security: String, Codable { + case aes128gcm = "aes-128-gcm" + case chacha20poly1305 = "chacha20-poly1305" + case auto = "auto" + case none = "none" + } + } + } + } + + struct Dns: Codable { + var network: String = "" // "tcp" | "udp" | "" + var address: String = "" + var port: Int? + } + + init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + `protocol` = try container.decode(Protocol.self, forKey: CodingKeys.`protocol`) + + tag = container.contains(.tag) ? try container.decode(String.self, forKey: .tag) : nil + sendThrough = container.contains(.sendThrough) ? try container.decode(String.self, forKey: CodingKeys.sendThrough) : nil + proxySettings = container.contains(.proxySettings) ? try container.decode(Settings.self, forKey: CodingKeys.proxySettings) : nil + streamSettings = container.contains(.streamSettings) ? try container.decode(StreamSettings.self, forKey: CodingKeys.streamSettings) : nil + mux = container.contains(.mux) ? try container.decode(Mux.self, forKey: CodingKeys.mux) : nil + + switch `protocol` { + case .blackhole: + settingBlackhole = try container.decode(Blackhole.self, forKey: CodingKeys.settings) + case .freedom: + settingFreedom = try container.decode(Freedom.self, forKey: CodingKeys.settings) + case .shadowsocks: + settingShadowsocks = try container.decode(Shadowsocks.self, forKey: CodingKeys.settings) + case .socks: + settingSocks = try container.decode(Socks.self, forKey: CodingKeys.settings) + case .vmess: + settingVMess = try container.decode(VMess.self, forKey: CodingKeys.settings) + case .dns: + settingDns = try container.decode(Dns.self, forKey: CodingKeys.settings) + } + } + + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(`protocol`, forKey: .`protocol`) + + tag == nil ? nil : try container.encode(tag, forKey: .tag) + streamSettings == nil ? nil : try container.encode(streamSettings, forKey: .streamSettings) + (sendThrough == nil || sendThrough!.count <= 0) ? nil : try container.encode(sendThrough, forKey: .sendThrough) + proxySettings == nil ? nil : try container.encode(proxySettings, forKey: .proxySettings) + mux == nil ? nil : try container.encode(mux, forKey: .mux) + + switch `protocol` { + case .shadowsocks: + try container.encode(self.settingShadowsocks, forKey: .settings) + case .socks: + try container.encode(self.settingSocks, forKey: .settings) + case .vmess: + try container.encode(self.settingVMess, forKey: .settings) + case .blackhole: + try container.encode(self.settingBlackhole, forKey: .settings) + case .freedom: + try container.encode(self.settingFreedom, forKey: .settings) + case .dns: + try container.encode(self.settingDns, forKey: .settings) + } + } + } + + // MARK: - Transport + + struct Transport: Codable { + var tlsSettings: StreamSettings.TlsSettings? + var tcpSettings: StreamSettings.TcpSettings? + var kcpSettings: StreamSettings.KcpSettings? + var wsSettings: StreamSettings.WsSettings? + var httpSettings: StreamSettings.HttpSettings? + var dsSettings: StreamSettings.DsSettings? + var quicSettings: StreamSettings.QuicSettings? + } + + // MARK: - StreamSettings + + struct StreamSettings: Codable { + var network: network = .tcp + var security: security = .none + var sockopt: Sockopt? + var tlsSettings: TlsSettings? + var tcpSettings: TcpSettings? + var kcpSettings: KcpSettings? + var wsSettings: WsSettings? + var httpSettings: HttpSettings? + var dsSettings: DsSettings? + var quicSettings: QuicSettings? + + enum network: String, Codable { + case tcp + case kcp + case ws + case http + case h2 + case domainsocket + case quic + } + + enum security: String, Codable { + case none + case tls + } + + struct TlsSettings: Codable { + var serverName: String? + var alpn: String? + var allowInsecure: Bool? + var allowInsecureCiphers: Bool? + var certificates: TlsCertificates? + + struct TlsCertificates: Codable { + enum usage: String, Codable { + case encipherment + case verify + case issue + } + + var usage: usage? = .encipherment + var certificateFile: String? + var keyFile: String? + var certificate: String? + var key: String? + } + } + + struct TcpSettings: Codable { + var header: Header = Header() + + struct Header: Codable { + var type: String = "none" + var request: Request? + var response: Response? + + struct Request: Codable { + var version: String = "" + var method: String = "" + var path: [String] = [] + var headers: Headers = Headers() + + struct Headers: Codable { + var host: [String] = [] + var userAgent: [String] = [] + var acceptEncoding: [String] = [] + var connection: [String] = [] + var pragma: String = "" + + enum CodingKeys: String, CodingKey { + case host = "Host" + case userAgent = "User-Agent" + case acceptEncoding = "Accept-Encoding" + case connection = "Connection" + case pragma = "Pragma" + } + } + } + + struct Response: Codable { + var version, status, reason: String? + var headers: Headers? + + struct Headers: Codable { + var contentType, transferEncoding, connection: [String]? + var pragma: String? + + enum CodingKeys: String, CodingKey { + case contentType = "Content-Type" + case transferEncoding = "Transfer-Encoding" + case connection = "Connection" + case pragma = "Pragma" + } + } + } + } + } + + struct KcpSettings: Codable { + var mtu: Int = 1350 + var tti: Int = 20 + var uplinkCapacity: Int = 50 + var downlinkCapacity: Int = 20 + var congestion: Bool = false + var readBufferSize: Int = 1 + var writeBufferSize: Int = 1 + var header: Header = Header() + + struct Header: Codable { + var type: Type = .none + + enum `Type`: String, Codable { + case none = "none" + case srtp = "srtp" + case utp = "utp" + case wechatVideo = "wechat-video" + case dtls = "dtls" + case wireguard = "wireguard" + } + } + } + + struct WsSettings: Codable { + var path: String = "" + var headers: Header = Header() + + struct Header: Codable { + var host: String = "" + } + } + + struct HttpSettings: Codable { + var host: [String] = [""] + var path: String = "" + } + + struct DsSettings: Codable { + var path: String = "" + } + + struct Sockopt: Codable { + var mark: Int = 0 + var tcpFastOpen: Bool = false + var tproxy: tproxy = .off // only for linux + + enum tproxy: String, Codable { + case redirect + case tproxy + case off + } + } + + struct QuicSettings: Codable { + var security: Security = .none + var key: String = "" + var header: Header = Header() + + struct Header: Codable { + var type: Type = .none + + enum `Type`: String, Codable { + case none = "none" + case srtp = "srtp" + case utp = "utp" + case wechatVideo = "wechat-video" + case dtls = "dtls" + case wireguard = "wireguard" + } + } + + enum Security: String, Codable { + case none = "none" + case aes128gcm = "aes-128-gcm" + case chacha20poly1305 = "chacha20-poly1305" + } + } + } + +} From 162b7b71202bdf66a10d2e7d18de1a70c31c196c Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Sat, 5 Aug 2023 10:58:55 +0200 Subject: [PATCH 008/106] feat(v2ray): create VmessEndpoint.swift --- IVPNClient.xcodeproj/project.pbxproj | 8 ++ IVPNClient/Models/V2Ray/VmessEndpoint.swift | 110 ++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 IVPNClient/Models/V2Ray/VmessEndpoint.swift diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index 05632bc54..aa5eeca96 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -38,6 +38,9 @@ 820EA86B232242F800E16B2D /* ApiRequestDI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821429BA22FC36100056B8FF /* ApiRequestDI.swift */; }; 820EA86C2322430700E16B2D /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821429B622FC2BE90056B8FF /* Result.swift */; }; 820EA86E232264EC00E16B2D /* SuccessResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 820EA86D232264EC00E16B2D /* SuccessResult.swift */; }; + 8210A3342A7E2ACA001907E0 /* VmessEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8210A3332A7E2AC9001907E0 /* VmessEndpoint.swift */; }; + 8210A3352A7E2ACA001907E0 /* VmessEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8210A3332A7E2AC9001907E0 /* VmessEndpoint.swift */; }; + 8210A3362A7E2ACA001907E0 /* VmessEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8210A3332A7E2AC9001907E0 /* VmessEndpoint.swift */; }; 821429B722FC2BE90056B8FF /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821429B622FC2BE90056B8FF /* Result.swift */; }; 821429B922FC2EA40056B8FF /* ApiService+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821429B822FC2EA40056B8FF /* ApiService+Ext.swift */; }; 821429BB22FC36100056B8FF /* ApiRequestDI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821429BA22FC36100056B8FF /* ApiRequestDI.swift */; }; @@ -472,6 +475,7 @@ 8208525B23FD64160008C112 /* MainViewController+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainViewController+Ext.swift"; sourceTree = ""; }; 820EA86723223F7900E16B2D /* InterfaceResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InterfaceResult.swift; sourceTree = ""; }; 820EA86D232264EC00E16B2D /* SuccessResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuccessResult.swift; sourceTree = ""; }; + 8210A3332A7E2AC9001907E0 /* VmessEndpoint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VmessEndpoint.swift; sourceTree = ""; }; 821429B622FC2BE90056B8FF /* Result.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Result.swift; sourceTree = ""; }; 821429B822FC2EA40056B8FF /* ApiService+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ApiService+Ext.swift"; sourceTree = ""; }; 821429BA22FC36100056B8FF /* ApiRequestDI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiRequestDI.swift; sourceTree = ""; }; @@ -924,6 +928,7 @@ isa = PBXGroup; children = ( 8247C05F2A7CF54300A7C02F /* V2RayConfig.swift */, + 8210A3332A7E2AC9001907E0 /* VmessEndpoint.swift */, ); path = V2Ray; sourceTree = ""; @@ -2069,6 +2074,7 @@ 82E7169A2181E96F00D6B7C2 /* OpenVPNProtocol.swift in Sources */, 8205352A2302BEA3007BDD58 /* Array+Ext.swift in Sources */, 82E716882181E8E100D6B7C2 /* ProviderConfigurationKeys.swift in Sources */, + 8210A3362A7E2ACA001907E0 /* VmessEndpoint.swift in Sources */, 8247C0622A7CF54300A7C02F /* V2RayConfig.swift in Sources */, 82F638C5217DA89000410318 /* AddressType.swift in Sources */, 82EEB6DB25F961BC00915837 /* URL+Ext.swift in Sources */, @@ -2195,6 +2201,7 @@ 8247C0612A7CF54300A7C02F /* V2RayConfig.swift in Sources */, 82ED17552A1262BA00E7926D /* Interface.swift in Sources */, 82E716812181E8AF00D6B7C2 /* TunnelType.swift in Sources */, + 8210A3352A7E2ACA001907E0 /* VmessEndpoint.swift in Sources */, 82A208C121BAAC6C00C9AD44 /* Config.swift in Sources */, 82ED174B2A125D0900E7926D /* InterfaceResult.swift in Sources */, ); @@ -2313,6 +2320,7 @@ 82A160BB221C4E2000730577 /* Server+CoreDataProperties.swift in Sources */, 8270753622AFC5B90067C323 /* StringProtocol+Ext.swift in Sources */, 82526BEF24123D2900E00880 /* NetworkViewTableCell.swift in Sources */, + 8210A3342A7E2ACA001907E0 /* VmessEndpoint.swift in Sources */, 82DEF021244714F000CCB5CD /* ScannerView.swift in Sources */, 826FBDA52461848A00B9E464 /* ServiceDuration.swift in Sources */, 9CB2CE411DB2594A007A4D2D /* VPNServerList.swift in Sources */, diff --git a/IVPNClient/Models/V2Ray/VmessEndpoint.swift b/IVPNClient/Models/V2Ray/VmessEndpoint.swift new file mode 100644 index 000000000..98fb6ccc4 --- /dev/null +++ b/IVPNClient/Models/V2Ray/VmessEndpoint.swift @@ -0,0 +1,110 @@ +// +// VmessEndpoint.swift +// IVPN iOS app +// https://github.com/ivpn/ios-app +// +// Created by Juraj Hilje on 2023-08-05. +// Copyright (c) 2023 Privatus Limited. +// +// This file is part of the IVPN iOS app. +// +// The IVPN iOS app 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. +// +// The IVPN iOS app 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 the IVPN iOS app. If not, see . +// + +import Foundation + +struct VmessEndpoint: Codable, Hashable { + + var url: String? = nil + var path: String? = nil + var info: Dictionary = [:] + + enum InfoKey: String, CodingKey { + case address = "add" + case port + case type + case host + case aid + case uuid = "id" + case tls + case net + case ps + } + + enum CodingKeys: String, CodingKey { + case url + case path + case info + } + + static func generatePoints(with vmessUrls:[String]) -> [VmessEndpoint] { + var array: [VmessEndpoint] = Array() + for url in vmessUrls { + if url.count > 0 && url.hasPrefix("vmess://") { + array.append(VmessEndpoint.init(url)) + } + } + return array + } + + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + url != nil ? try container.encode(url, forKey: .url) : nil + path != nil ? try container.encode(path, forKey: .path) : nil + + if !info.isEmpty, let jsonData = try? JSONSerialization.data(withJSONObject: info) { + try container.encode(jsonData, forKey: .info) + } + } + + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + url = (values.contains(.url) == true) ? try values.decode(String.self, forKey: .url) : nil + path = (values.contains(.path) == true) ? try values.decode(String.self, forKey: .path) : nil + + if values.contains(.info), let jsonData = try? values.decode(Data.self, forKey: .info) { + info = (try? JSONSerialization.jsonObject(with: jsonData) as? [String: Any]) ?? [String: Any]() + } else { + info = [String: Any]() + } + } + + init(_ url: String?) { + self.url = url?.replacingOccurrences(of: "\r", with: "") + self.path = self.url?.replacingOccurrences(of: "vmess://", with: "") + + guard let path = self.path else { + return + } + + guard let base64Data = Data.init(base64Encoded: path) else { + return + } + + guard let dic = try? JSONSerialization.jsonObject(with: base64Data, options: [.allowFragments, .fragmentsAllowed, .mutableContainers, .mutableLeaves]) else { + return + } + + self.info = dic as! Dictionary + } + + static func == (lhs: VmessEndpoint, rhs: VmessEndpoint) -> Bool { + return lhs.url == rhs.url + } + + func hash(into hasher: inout Hasher) { + hasher.combine(url) + } + +} + From a02f5cd44ef74687fe62d96dbc0b688c8b79d547 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Tue, 22 Aug 2023 16:56:09 +0200 Subject: [PATCH 009/106] docs: update licence header --- IVPNClient/Models/V2Ray/V2RayConfig.swift | 2 +- IVPNClient/Models/V2Ray/VmessEndpoint.swift | 2 +- IVPNClient/Utilities/Extensions/Decodable+Ext.swift | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/IVPNClient/Models/V2Ray/V2RayConfig.swift b/IVPNClient/Models/V2Ray/V2RayConfig.swift index 8b60fa508..6bfb1d971 100644 --- a/IVPNClient/Models/V2Ray/V2RayConfig.swift +++ b/IVPNClient/Models/V2Ray/V2RayConfig.swift @@ -4,7 +4,7 @@ // https://github.com/ivpn/ios-app // // Created by Juraj Hilje on 2023-08-04. -// Copyright (c) 2023 Privatus Limited. +// Copyright (c) 2023 IVPN Limited. // // This file is part of the IVPN iOS app. // diff --git a/IVPNClient/Models/V2Ray/VmessEndpoint.swift b/IVPNClient/Models/V2Ray/VmessEndpoint.swift index 98fb6ccc4..590999fb2 100644 --- a/IVPNClient/Models/V2Ray/VmessEndpoint.swift +++ b/IVPNClient/Models/V2Ray/VmessEndpoint.swift @@ -4,7 +4,7 @@ // https://github.com/ivpn/ios-app // // Created by Juraj Hilje on 2023-08-05. -// Copyright (c) 2023 Privatus Limited. +// Copyright (c) 2023 IVPN Limited. // // This file is part of the IVPN iOS app. // diff --git a/IVPNClient/Utilities/Extensions/Decodable+Ext.swift b/IVPNClient/Utilities/Extensions/Decodable+Ext.swift index 28d5cd91e..0ed2810ca 100644 --- a/IVPNClient/Utilities/Extensions/Decodable+Ext.swift +++ b/IVPNClient/Utilities/Extensions/Decodable+Ext.swift @@ -4,7 +4,7 @@ // https://github.com/ivpn/ios-app // // Created by Juraj Hilje on 2023-08-04. -// Copyright (c) 2023 Privatus Limited. +// Copyright (c) 2023 IVPN Limited. // // This file is part of the IVPN iOS app. // From 2247dc2d176eb65d57daa8d9eb3856d504469442 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Wed, 23 Aug 2023 09:59:02 +0200 Subject: [PATCH 010/106] feat: create V2RayCore.swift --- IVPNClient.xcodeproj/project.pbxproj | 4 ++ IVPNClient/Models/V2Ray/V2RayCore.swift | 69 +++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 IVPNClient/Models/V2Ray/V2RayCore.swift diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index aa5eeca96..13aa515d6 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -54,6 +54,7 @@ 821CA2D7287C5AB20067F70D /* PortViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821CA2D6287C5AB20067F70D /* PortViewController.swift */; }; 821CA2DB288039670067F70D /* PortTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821CA2DA288039670067F70D /* PortTableViewCell.swift */; }; 821CA2DF288143470067F70D /* PortRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821CA2DE288143470067F70D /* PortRange.swift */; }; + 821E35582A95DCD200AEE5C7 /* V2RayCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821E35572A95DCD200AEE5C7 /* V2RayCore.swift */; }; 821F1C7E21FF544200107311 /* VPNServerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821F1C7D21FF544200107311 /* VPNServerViewModel.swift */; }; 821F604A240D21E3008072D7 /* ControlPanelViewController+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821F6049240D21E3008072D7 /* ControlPanelViewController+Ext.swift */; }; 8221377B2227E75E001E1BF5 /* CustomDNSViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8221377A2227E75E001E1BF5 /* CustomDNSViewController.swift */; }; @@ -486,6 +487,7 @@ 821CA2D6287C5AB20067F70D /* PortViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortViewController.swift; sourceTree = ""; }; 821CA2DA288039670067F70D /* PortTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortTableViewCell.swift; sourceTree = ""; }; 821CA2DE288143470067F70D /* PortRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortRange.swift; sourceTree = ""; }; + 821E35572A95DCD200AEE5C7 /* V2RayCore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = V2RayCore.swift; sourceTree = ""; }; 821F1C7D21FF544200107311 /* VPNServerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNServerViewModel.swift; sourceTree = ""; }; 821F6049240D21E3008072D7 /* ControlPanelViewController+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ControlPanelViewController+Ext.swift"; sourceTree = ""; }; 8221377A2227E75E001E1BF5 /* CustomDNSViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomDNSViewController.swift; sourceTree = ""; }; @@ -929,6 +931,7 @@ children = ( 8247C05F2A7CF54300A7C02F /* V2RayConfig.swift */, 8210A3332A7E2AC9001907E0 /* VmessEndpoint.swift */, + 821E35572A95DCD200AEE5C7 /* V2RayCore.swift */, ); path = V2Ray; sourceTree = ""; @@ -2370,6 +2373,7 @@ 82F638C2217DA89000410318 /* AddressType.swift in Sources */, 822920A02480FA3600476FC1 /* ServersSort.swift in Sources */, 826E61482428F8E60064F195 /* AccountViewController.swift in Sources */, + 821E35582A95DCD200AEE5C7 /* V2RayCore.swift in Sources */, 820079F42407D96D00EC2062 /* ConnectionInfoBoxView.swift in Sources */, 821429BB22FC36100056B8FF /* ApiRequestDI.swift in Sources */, 82AB0877291A6B9C0084625A /* CustomPort+CoreDataClass.swift in Sources */, diff --git a/IVPNClient/Models/V2Ray/V2RayCore.swift b/IVPNClient/Models/V2Ray/V2RayCore.swift new file mode 100644 index 000000000..0e4d573dc --- /dev/null +++ b/IVPNClient/Models/V2Ray/V2RayCore.swift @@ -0,0 +1,69 @@ +// +// V2RayCore.swift +// IVPN iOS app +// https://github.com/ivpn/ios-app +// +// Created by Juraj Hilje on 2023-08-23. +// Copyright (c) 2023 IVPN Limited. +// +// This file is part of the IVPN iOS app. +// +// The IVPN iOS app 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. +// +// The IVPN iOS app 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 the IVPN iOS app. If not, see . +// + +import Foundation +import V2Ray + +class V2RayCore { + + // MARK: - Properties - + + static let shared = V2RayCore() + var serverPoint: VmessEndpoint? + private var core: CoreInstance? + + // MARK: - Methods - + + func start(serverPoint: VmessEndpoint, completion: ((_ error: Error?) -> Void)?) { + if core != nil { + try? core?.close() + core = nil + } + + let config = V2RayConfig.parse(fromJsonFile: "config")! + let configData = try? JSONEncoder().encode(config) + var startError: Error? = nil + + do { + let config = CoreConfig.init() + core = CoreNew(config, nil) + try core?.start() + self.serverPoint = serverPoint + } catch let error { + startError = error + self.serverPoint = nil + } + + completion?(startError) + } + + func close() { + guard core != nil else { + return + } + + try? core?.close() + serverPoint = nil + } + +} From cbb22a25efefdb8db536907ea2d9e9ea1f9b46fd Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Wed, 23 Aug 2023 10:16:09 +0200 Subject: [PATCH 011/106] feat: create V2Ray/config.json --- IVPNClient.xcodeproj/project.pbxproj | 4 ++++ IVPNClient/Models/V2Ray/config.json | 8 ++++++++ 2 files changed, 12 insertions(+) create mode 100644 IVPNClient/Models/V2Ray/config.json diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index 13aa515d6..72c270844 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -55,6 +55,7 @@ 821CA2DB288039670067F70D /* PortTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821CA2DA288039670067F70D /* PortTableViewCell.swift */; }; 821CA2DF288143470067F70D /* PortRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821CA2DE288143470067F70D /* PortRange.swift */; }; 821E35582A95DCD200AEE5C7 /* V2RayCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821E35572A95DCD200AEE5C7 /* V2RayCore.swift */; }; + 821E355A2A95F77700AEE5C7 /* config.json in Resources */ = {isa = PBXBuildFile; fileRef = 821E35592A95F77700AEE5C7 /* config.json */; }; 821F1C7E21FF544200107311 /* VPNServerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821F1C7D21FF544200107311 /* VPNServerViewModel.swift */; }; 821F604A240D21E3008072D7 /* ControlPanelViewController+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821F6049240D21E3008072D7 /* ControlPanelViewController+Ext.swift */; }; 8221377B2227E75E001E1BF5 /* CustomDNSViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8221377A2227E75E001E1BF5 /* CustomDNSViewController.swift */; }; @@ -488,6 +489,7 @@ 821CA2DA288039670067F70D /* PortTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortTableViewCell.swift; sourceTree = ""; }; 821CA2DE288143470067F70D /* PortRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortRange.swift; sourceTree = ""; }; 821E35572A95DCD200AEE5C7 /* V2RayCore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = V2RayCore.swift; sourceTree = ""; }; + 821E35592A95F77700AEE5C7 /* config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = config.json; sourceTree = ""; }; 821F1C7D21FF544200107311 /* VPNServerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNServerViewModel.swift; sourceTree = ""; }; 821F6049240D21E3008072D7 /* ControlPanelViewController+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ControlPanelViewController+Ext.swift"; sourceTree = ""; }; 8221377A2227E75E001E1BF5 /* CustomDNSViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomDNSViewController.swift; sourceTree = ""; }; @@ -932,6 +934,7 @@ 8247C05F2A7CF54300A7C02F /* V2RayConfig.swift */, 8210A3332A7E2AC9001907E0 /* VmessEndpoint.swift */, 821E35572A95DCD200AEE5C7 /* V2RayCore.swift */, + 821E35592A95F77700AEE5C7 /* config.json */, ); path = V2Ray; sourceTree = ""; @@ -1994,6 +1997,7 @@ files = ( 9CDDD5B91D9D2F9F00D39924 /* LaunchScreen.storyboard in Resources */, 9CDDD5B61D9D2F9F00D39924 /* Assets.xcassets in Resources */, + 821E355A2A95F77700AEE5C7 /* config.json in Resources */, 9CB2CE541DB2A999007A4D2D /* servers.json in Resources */, 8269CD8F2164A8C700D083A1 /* servers-dev.json in Resources */, 9CDDD5B41D9D2F9F00D39924 /* Main.storyboard in Resources */, diff --git a/IVPNClient/Models/V2Ray/config.json b/IVPNClient/Models/V2Ray/config.json new file mode 100644 index 000000000..2b87b133a --- /dev/null +++ b/IVPNClient/Models/V2Ray/config.json @@ -0,0 +1,8 @@ +{ + "policy": {}, + "log": {}, + "inbounds": [], + "outbounds": [], + "dns": {}, + "routing": {} +} From e70df08b4c3dcdf1c1455a0bfadce6876bc918a0 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Wed, 23 Aug 2023 13:24:36 +0200 Subject: [PATCH 012/106] feat: update V2RayCore.swift --- IVPNClient.xcodeproj/project.pbxproj | 27 +++++++++++++++++-------- IVPNClient/Models/V2Ray/V2RayCore.swift | 1 + 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index 72c270844..b0d7e86bd 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -47,15 +47,15 @@ 82152C9929F14B4C007FCECC /* KeyChain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82152C9829F14B4C007FCECC /* KeyChain.swift */; }; 82152C9B29F17568007FCECC /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 82152C9A29F17568007FCECC /* KeychainAccess */; }; 821AFA1323602B71001EF617 /* SettingsScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821AFA1223602B71001EF617 /* SettingsScreenTests.swift */; }; - 821BB5C02A7CF0C9005D9D64 /* V2Ray.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 821BB5BF2A7CF0C9005D9D64 /* V2Ray.xcframework */; }; - 821BB5C12A7CF0C9005D9D64 /* V2Ray.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 821BB5BF2A7CF0C9005D9D64 /* V2Ray.xcframework */; }; - 821BB5C22A7CF0C9005D9D64 /* V2Ray.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 821BB5BF2A7CF0C9005D9D64 /* V2Ray.xcframework */; }; 821BDE02224A6EC700F592BF /* AppKeyManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821BDE01224A6EC700F592BF /* AppKeyManagerTests.swift */; }; 821CA2D7287C5AB20067F70D /* PortViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821CA2D6287C5AB20067F70D /* PortViewController.swift */; }; 821CA2DB288039670067F70D /* PortTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821CA2DA288039670067F70D /* PortTableViewCell.swift */; }; 821CA2DF288143470067F70D /* PortRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821CA2DE288143470067F70D /* PortRange.swift */; }; 821E35582A95DCD200AEE5C7 /* V2RayCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821E35572A95DCD200AEE5C7 /* V2RayCore.swift */; }; 821E355A2A95F77700AEE5C7 /* config.json in Resources */ = {isa = PBXBuildFile; fileRef = 821E35592A95F77700AEE5C7 /* config.json */; }; + 821E355F2A96234B00AEE5C7 /* V2Ray.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 821E355E2A96234B00AEE5C7 /* V2Ray.xcframework */; }; + 821E35602A96234B00AEE5C7 /* V2Ray.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 821E355E2A96234B00AEE5C7 /* V2Ray.xcframework */; }; + 821E35612A96234B00AEE5C7 /* V2Ray.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 821E355E2A96234B00AEE5C7 /* V2Ray.xcframework */; }; 821F1C7E21FF544200107311 /* VPNServerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821F1C7D21FF544200107311 /* VPNServerViewModel.swift */; }; 821F604A240D21E3008072D7 /* ControlPanelViewController+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821F6049240D21E3008072D7 /* ControlPanelViewController+Ext.swift */; }; 8221377B2227E75E001E1BF5 /* CustomDNSViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8221377A2227E75E001E1BF5 /* CustomDNSViewController.swift */; }; @@ -432,6 +432,16 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ + 821E355D2A96227E00AEE5C7 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; 9C7840B420CD8A8A00335736 /* Embed Foundation Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -483,13 +493,13 @@ 821429BA22FC36100056B8FF /* ApiRequestDI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiRequestDI.swift; sourceTree = ""; }; 82152C9829F14B4C007FCECC /* KeyChain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyChain.swift; sourceTree = ""; }; 821AFA1223602B71001EF617 /* SettingsScreenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreenTests.swift; sourceTree = ""; }; - 821BB5BF2A7CF0C9005D9D64 /* V2Ray.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = V2Ray.xcframework; path = Frameworks/V2Ray.xcframework; sourceTree = ""; }; 821BDE01224A6EC700F592BF /* AppKeyManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppKeyManagerTests.swift; sourceTree = ""; }; 821CA2D6287C5AB20067F70D /* PortViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortViewController.swift; sourceTree = ""; }; 821CA2DA288039670067F70D /* PortTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortTableViewCell.swift; sourceTree = ""; }; 821CA2DE288143470067F70D /* PortRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortRange.swift; sourceTree = ""; }; 821E35572A95DCD200AEE5C7 /* V2RayCore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = V2RayCore.swift; sourceTree = ""; }; 821E35592A95F77700AEE5C7 /* config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = config.json; sourceTree = ""; }; + 821E355E2A96234B00AEE5C7 /* V2Ray.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = V2Ray.xcframework; path = Frameworks/V2Ray.xcframework; sourceTree = ""; }; 821F1C7D21FF544200107311 /* VPNServerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNServerViewModel.swift; sourceTree = ""; }; 821F6049240D21E3008072D7 /* ControlPanelViewController+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ControlPanelViewController+Ext.swift"; sourceTree = ""; }; 8221377A2227E75E001E1BF5 /* CustomDNSViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomDNSViewController.swift; sourceTree = ""; }; @@ -776,7 +786,7 @@ buildActionMask = 2147483647; files = ( 82B6052F21708575004B40E6 /* NetworkExtension.framework in Frameworks */, - 821BB5C22A7CF0C9005D9D64 /* V2Ray.xcframework in Frameworks */, + 821E35612A96234B00AEE5C7 /* V2Ray.xcframework in Frameworks */, 82BF79622A2F8DDC00061972 /* liboqs.a in Frameworks */, 824B86E126D42A5700D0101A /* WireGuardKit in Frameworks */, 829F5FCB29A13CF2009E1AD3 /* KeychainAccess in Frameworks */, @@ -805,7 +815,7 @@ buildActionMask = 2147483647; files = ( 9CF7E35A20F7A86E008E0EC5 /* NetworkExtension.framework in Frameworks */, - 821BB5C12A7CF0C9005D9D64 /* V2Ray.xcframework in Frameworks */, + 821E35602A96234B00AEE5C7 /* V2Ray.xcframework in Frameworks */, 829407C12A3DCE9200E6B68E /* liboqs.a in Frameworks */, 82968A34298A970500077E0A /* TunnelKitOpenVPNAppExtension in Frameworks */, 829F5FC929A13CEA009E1AD3 /* KeychainAccess in Frameworks */, @@ -817,7 +827,7 @@ buildActionMask = 2147483647; files = ( 82D598C621A6A5C7000FABDE /* SystemConfiguration.framework in Frameworks */, - 821BB5C02A7CF0C9005D9D64 /* V2Ray.xcframework in Frameworks */, + 821E355F2A96234B00AEE5C7 /* V2Ray.xcframework in Frameworks */, 9CB2CE311DAF9227007A4D2D /* CoreData.framework in Frameworks */, 9C6942251DD0CBF800F9A801 /* NetworkExtension.framework in Frameworks */, 82486FAD2A277058009B53F4 /* liboqs.a in Frameworks */, @@ -840,7 +850,7 @@ 584496306C3B9383149618CE /* Frameworks */ = { isa = PBXGroup; children = ( - 821BB5BF2A7CF0C9005D9D64 /* V2Ray.xcframework */, + 821E355E2A96234B00AEE5C7 /* V2Ray.xcframework */, 8294BC8D22A126C900328932 /* TunnelKit.framework */, 8294BC8B22A10F4100328932 /* TunnelKit.framework */, 824F56072233FE6F00BCDD5C /* libwg-go.a */, @@ -1796,6 +1806,7 @@ 9CDDD5A91D9D2F9E00D39924 /* Resources */, 9C7840B420CD8A8A00335736 /* Embed Foundation Extensions */, 9CB2CE481DB28B8B007A4D2D /* Fetch servers.json */, + 821E355D2A96227E00AEE5C7 /* Embed Frameworks */, ); buildRules = ( ); diff --git a/IVPNClient/Models/V2Ray/V2RayCore.swift b/IVPNClient/Models/V2Ray/V2RayCore.swift index 0e4d573dc..358190ad3 100644 --- a/IVPNClient/Models/V2Ray/V2RayCore.swift +++ b/IVPNClient/Models/V2Ray/V2RayCore.swift @@ -46,6 +46,7 @@ class V2RayCore { do { let config = CoreConfig.init() + try config.xxX_Marshal(configData, deterministic: true) core = CoreNew(config, nil) try core?.start() self.serverPoint = serverPoint From 455e0f880845a80fcd61451909ea2dec16263975 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Wed, 23 Aug 2023 13:38:14 +0200 Subject: [PATCH 013/106] feat: update V2Ray/config.json --- IVPNClient/Models/V2Ray/config.json | 83 ++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/IVPNClient/Models/V2Ray/config.json b/IVPNClient/Models/V2Ray/config.json index 2b87b133a..d069697f1 100644 --- a/IVPNClient/Models/V2Ray/config.json +++ b/IVPNClient/Models/V2Ray/config.json @@ -1,8 +1,79 @@ { - "policy": {}, - "log": {}, - "inbounds": [], - "outbounds": [], - "dns": {}, - "routing": {} + "log":{ + "loglevel":"debug" + }, + "inbounds":[ + { + "port":"16661", + "protocol":"dokodemo-door", + "settings":{ + "address":"", + "port":0, + "network":"udp" + } + } + ], + "outbounds":[ + { + "tag":"proxy", + "protocol":"vmess", + "settings":{ + "vnext":[ + { + "address":"", + "port":0, + "users":[ + { + "id":"", + "alterId":0, + "security":"none" + } + ] + } + ] + }, + "streamSettings":{ + "network":"quic", + "security":"tls", + "quicSettings":{ + "security":"", + "key":"", + "header":{ + "type":"srtp" + } + }, + "tlsSettings":{ + "serverName":"xb1.gw.inet-telecom.com" + }, + "tcpSettings":{ + "header":{ + "type":"http", + "request":{ + "version":"1.1", + "method":"GET", + "path":[ + "/" + ], + "headers":{ + "Host":[ + "www.inet-telecom.com" + ], + "User-Agent":[ + "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36", + "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46" + ], + "Accept-Encoding":[ + "gzip, deflate" + ], + "Connection":[ + "keep-alive" + ], + "Pragma":"no-cache" + } + } + } + } + } + } + ] } From 94eca7a7da0324082d2e26ece3e022f7b0958aa4 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Thu, 24 Aug 2023 09:15:23 +0200 Subject: [PATCH 014/106] feat: update V2RayConfig.swift --- IVPNClient/Models/V2Ray/V2RayConfig.swift | 681 ++++------------------ 1 file changed, 123 insertions(+), 558 deletions(-) diff --git a/IVPNClient/Models/V2Ray/V2RayConfig.swift b/IVPNClient/Models/V2Ray/V2RayConfig.swift index 6bfb1d971..aa82de83f 100644 --- a/IVPNClient/Models/V2Ray/V2RayConfig.swift +++ b/IVPNClient/Models/V2Ray/V2RayConfig.swift @@ -24,610 +24,175 @@ import Foundation struct V2RayConfig: Codable { - var log: Log? - var api: Api? - var dns: Dns? - var stats: Stats? - var routing: Routing? - var policy: Policy? - var inbounds: [Inbound]? - var outbounds: [Outbound]? - var transport: Transport? -} - -extension V2RayConfig { - - // MARK: - Log - - struct Log: Codable { - var loglevel: Level = .info - var error: String = "" - var access: String = "" - - enum Level: String, Codable { - case debug - case info - case warning - case error - case none - } - } - // MARK: - API + // MARK: - Properties - - struct Api: Codable {} + var log: Log + var inbounds: [Inbound] + var outbounds: [Outbound] - // MARK: - DNS - - struct Dns: Codable { - var servers = [String]() - } - - // MARK: - Stats - - struct Stats: Codable {} - - // MARK: - Routing - - struct Routing: Codable { - var strategy: String = "rules" - var settings: Setting = Setting() - - struct Setting: Codable { - enum domainStrategy: String, Codable { - case AsIs - case IPIfNonMatch - case IPOnDemand - } - - var domainStrategy: domainStrategy = .IPIfNonMatch - var rules: [Rule] = [Rule()] - - struct Rule: Codable { - var type: String? = "field" - var domain: [String]? = [] - var ip: [String]? = [] - var port: String? - var network: String? - var source: [String]? - var user: [String]? - var inboundTag: [String]? - var `protocol`: [String]? // ["http", "tls", "bittorrent"] - var outboundTag: String? = "direct" - } - } + struct Log: Codable { + var loglevel: String } - // MARK: - Policy - - struct Policy: Codable {} - - // MARK: - Inbound - struct Inbound: Codable { - var port: String = "" - var listen: String = "" - var `protocol`: Protocol = .socks - var tag: String? = nil - var streamSettings: StreamSettings? = nil - var sniffing: Sniffing? = nil - var allocate: Allocate? = nil - - var settingHttp: Http = Http() - var settingSocks: Socks = Socks() - var settingShadowsocks: Shadowsocks? = nil - var settingVMess: VMess? = nil - - enum CodingKeys: String, CodingKey { - case port - case listen - case `protocol` - case tag - case streamSettings - case sniffing - case settings - } - - enum `Protocol`: String, Codable { - case http - case shadowsocks - case socks - case vmess - } - - struct Allocate: Codable { - var strategy: strategy = .always // always or random - var refresh: Int = 2 // val is 2-5 where strategy = random - var concurrency: Int = 3 // suggest 3, min 1 - - enum strategy: String, Codable { - case always - case random - } - } - - struct Sniffing: Codable { - var enabled: Bool = false - var destOverride: [dest] = [.tls, .http] - - enum dest: String, Codable { - case tls - case http - } - } - - struct Http: Codable { - var timeout: Int = 360 - var allowTransparent: Bool? - var userLevel: Int? - var accounts: [Account]? - - struct Account: Codable { - var user: String? - var pass: String? - } - } - - struct Shadowsocks: Codable { - var email, method, password: String? - var udp: Bool = false - var level: Int = 0 - var ota: Bool = true - var network: String = "tcp" // "tcp" | "udp" | "tcp,udp" - } - - struct Socks: Codable { - var auth: String = "noauth" // noauth | password - var accounts: [Account]? - var udp: Bool = true - var ip: String? - var timeout: Int = 360 - var userLevel: Int? - - struct Account: Codable { - var user: String? - var pass: String? - } - } - - struct VMess: Codable { - var clients: [Client]? - var `default`: Default? = Default() - var detour:Detour? - var disableInsecureEncryption: Bool = false - - struct Client: Codable { - var id: String? - var level: Int = 0 - var alterId: Int = 64 - var email: String? - } - - struct Detour: Codable { - var to: String? - } - - struct Default: Codable { - var level: Int = 0 - var alterId: Int = 64 - } - } - - init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - port = try container.decode(String.self, forKey: .port) - listen = try container.decode(String.self, forKey: .listen) - `protocol` = try container.decode(Protocol.self, forKey: .`protocol`) - - tag = container.contains(.tag) ? try container.decode(String.self, forKey: .tag) : nil - streamSettings = container.contains(.streamSettings) ? try container.decode(StreamSettings.self, forKey: CodingKeys.streamSettings) : nil - sniffing = container.contains(.sniffing) ? try container.decode(Sniffing.self, forKey: CodingKeys.sniffing) : nil - - switch `protocol` { - case .http: - settingHttp = try container.decode(Http.self, forKey: CodingKeys.settings) - case .shadowsocks: - settingShadowsocks = try container.decode(Shadowsocks.self, forKey: CodingKeys.settings) - case .socks: - settingSocks = try container.decode(Socks.self, forKey: CodingKeys.settings) - case .vmess: - settingVMess = try container.decode(VMess.self, forKey: CodingKeys.settings) - } - } + var port: String + var `protocol`: String + var settings: Settings - func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(port, forKey: .port) - try container.encode(listen, forKey: .listen) - try container.encode(`protocol`, forKey: .`protocol`) - - tag == nil ? nil : try container.encode(tag, forKey: .tag) - streamSettings == nil ? nil : try container.encode(streamSettings, forKey: .streamSettings) - sniffing == nil ? nil : try container.encode(sniffing, forKey: .sniffing) - - switch `protocol` { - case .http: - try container.encode(self.settingHttp, forKey: .settings) - case .shadowsocks: - try container.encode(self.settingShadowsocks, forKey: .settings) - case .socks: - try container.encode(self.settingSocks, forKey: .settings) - case .vmess: - try container.encode(self.settingVMess, forKey: .settings) - } + struct Settings: Codable { + var address: String + var port: Int + var network: String } } - // MARK: - Outbound - struct Outbound: Codable { - var `protocol`: Protocol = .freedom - var sendThrough: String? = nil - var tag: String? = nil - var streamSettings: StreamSettings? = nil - var proxySettings: Settings? = nil - var mux: Mux? = nil - - var settingBlackhole: Blackhole? = nil - var settingFreedom: Freedom? = nil - var settingShadowsocks: Shadowsocks? = nil - var settingSocks: Socks? = nil - var settingVMess: VMess? = nil - var settingDns: Dns? = nil - - enum CodingKeys: String, CodingKey { - case sendThrough - case `protocol` - case tag - case streamSettings - case proxySettings - case mux - case settings - } + let tag: String + let `protocol`: String + var settings: Settings + var streamSettings: StreamSettings struct Settings: Codable { - var Tag: String? - } - - enum `Protocol`: String, Codable { - case blackhole - case freedom - case shadowsocks - case socks - case vmess - case dns - } - - struct Mux: Codable { - var enabled: Bool = false - var concurrency: Int? = 8 - } - - struct Blackhole: Codable { - var response: Response = Response() + var vnext: [Vnext] - struct Response: Codable { - var type: String? = "none" // none | http + struct Vnext: Codable { + var address: String + var port: Int + var users: [User] + + struct User: Codable { + var id: String + let alterId: Int + let security: String + } } } - struct Freedom: Codable { - var domainStrategy: String = "AsIs" // UseIP | AsIs - var redirect: String? - var userLevel: Int = 0 - } - - struct Shadowsocks: Codable { - var servers: [Server] = [Server()] + struct StreamSettings: Codable { + var network: String + var security: String? + var quicSettings: QuicSettings? + var tlsSettings: TlsSettings? + var tcpSettings: TcpSettings? - struct Server: Codable { - var email: String = "" - var address: String = "" - var port: Int = 0 - var method: Method = .aes256cfb - var password: String = "" - var ota: Bool = false - var level: Int = 0 + struct QuicSettings: Codable { + let security: String + let key: String + let header: Header + + struct Header: Codable { + let type: String + } } - enum Method: String, Codable { - case aes256cfb = "aes-256-cfb" - case aes128cfb = "aes-128-cfb" - case chacha20 = "chacha20" - case chacha20ietf = "chacha20-ietf" - case aes256gcm = "aes-256-gcm" - case aes128gcm = "aes-128-gcm" - case chacha20poly1305 = "chacha20-poly1305" - case chacha20ietfpoly1305 = "chacha20-ietf-poly1305" + struct TlsSettings: Codable { + var serverName: String } - } - - struct Socks: Codable { - var address: String = "" - var port: String = "" - var users: [User] = [User()] - struct User: Codable { - var user: String = "" - var pass: String = "" - var level: Int = 0 - } - } - - struct VMess: Codable { - var vnext: [Item] = [Item()] - - struct Item: Codable { - var address: String = "" - var port: Int = 443 - var users: [User] = [User()] + struct TcpSettings: Codable { + let header: Header - struct User: Codable { - var id: String = "" - var alterId: Int = 64 // 0-65535 - var level: Int? = 0 - var security: Security = .auto + struct Header: Codable { + let type: String + let request: Request - enum Security: String, Codable { - case aes128gcm = "aes-128-gcm" - case chacha20poly1305 = "chacha20-poly1305" - case auto = "auto" - case none = "none" + struct Request: Codable { + let version: String + let method: String + let path: [String] + let headers: Headers + + struct Headers: Codable { + let host: [String] + let userAgent: [String] + let acceptEncoding: [String] + let connection: [String] + let pragma: String + } } } } } - - struct Dns: Codable { - var network: String = "" // "tcp" | "udp" | "" - var address: String = "" - var port: Int? + } + + // MARK: - Methods - + + func getLocalPort() -> (port: Int, isTcp: Bool) { + guard inbounds.count > 0 else { + return (0, false) } - init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - `protocol` = try container.decode(Protocol.self, forKey: CodingKeys.`protocol`) - - tag = container.contains(.tag) ? try container.decode(String.self, forKey: .tag) : nil - sendThrough = container.contains(.sendThrough) ? try container.decode(String.self, forKey: CodingKeys.sendThrough) : nil - proxySettings = container.contains(.proxySettings) ? try container.decode(Settings.self, forKey: CodingKeys.proxySettings) : nil - streamSettings = container.contains(.streamSettings) ? try container.decode(StreamSettings.self, forKey: CodingKeys.streamSettings) : nil - mux = container.contains(.mux) ? try container.decode(Mux.self, forKey: CodingKeys.mux) : nil - - switch `protocol` { - case .blackhole: - settingBlackhole = try container.decode(Blackhole.self, forKey: CodingKeys.settings) - case .freedom: - settingFreedom = try container.decode(Freedom.self, forKey: CodingKeys.settings) - case .shadowsocks: - settingShadowsocks = try container.decode(Shadowsocks.self, forKey: CodingKeys.settings) - case .socks: - settingSocks = try container.decode(Socks.self, forKey: CodingKeys.settings) - case .vmess: - settingVMess = try container.decode(VMess.self, forKey: CodingKeys.settings) - case .dns: - settingDns = try container.decode(Dns.self, forKey: CodingKeys.settings) - } + let port = Int(inbounds[0].port)! + let isTcp = inbounds[0].settings.network == "tcp" + return (port, isTcp) + } + + mutating func setLocalPort(port: Int, isTcp: Bool) { + guard inbounds.count > 0 else { + return } - func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(`protocol`, forKey: .`protocol`) - - tag == nil ? nil : try container.encode(tag, forKey: .tag) - streamSettings == nil ? nil : try container.encode(streamSettings, forKey: .streamSettings) - (sendThrough == nil || sendThrough!.count <= 0) ? nil : try container.encode(sendThrough, forKey: .sendThrough) - proxySettings == nil ? nil : try container.encode(proxySettings, forKey: .proxySettings) - mux == nil ? nil : try container.encode(mux, forKey: .mux) - - switch `protocol` { - case .shadowsocks: - try container.encode(self.settingShadowsocks, forKey: .settings) - case .socks: - try container.encode(self.settingSocks, forKey: .settings) - case .vmess: - try container.encode(self.settingVMess, forKey: .settings) - case .blackhole: - try container.encode(self.settingBlackhole, forKey: .settings) - case .freedom: - try container.encode(self.settingFreedom, forKey: .settings) - case .dns: - try container.encode(self.settingDns, forKey: .settings) - } + inbounds[0].port = String(port) + if isTcp { + inbounds[0].settings.network = "tcp" + } else { + inbounds[0].settings.network = "udp" } } - // MARK: - Transport - - struct Transport: Codable { - var tlsSettings: StreamSettings.TlsSettings? - var tcpSettings: StreamSettings.TcpSettings? - var kcpSettings: StreamSettings.KcpSettings? - var wsSettings: StreamSettings.WsSettings? - var httpSettings: StreamSettings.HttpSettings? - var dsSettings: StreamSettings.DsSettings? - var quicSettings: StreamSettings.QuicSettings? + func createFromTemplate(outboundIp: String, outboundPort: Int, inboundIp: String, inboundPort: Int, outboundUserId: String) -> V2RayConfig { + var config = V2RayConfig.parse(fromJsonFile: "config")! + config.inbounds[0].settings.address = inboundIp + config.inbounds[0].settings.port = inboundPort + config.outbounds[0].settings.vnext[0].address = outboundIp + config.outbounds[0].settings.vnext[0].port = outboundPort + config.outbounds[0].settings.vnext[0].users[0].id = outboundUserId + + return config } - // MARK: - StreamSettings - - struct StreamSettings: Codable { - var network: network = .tcp - var security: security = .none - var sockopt: Sockopt? - var tlsSettings: TlsSettings? - var tcpSettings: TcpSettings? - var kcpSettings: KcpSettings? - var wsSettings: WsSettings? - var httpSettings: HttpSettings? - var dsSettings: DsSettings? - var quicSettings: QuicSettings? + func createQuick(outboundIp: String, outboundPort: Int, inboundIp: String, inboundPort: Int, outboundUserId: String, tlsSrvName: String) -> V2RayConfig { + var config = createFromTemplate(outboundIp: outboundIp, outboundPort: outboundPort, inboundIp: inboundIp, inboundPort: inboundPort, outboundUserId: outboundUserId) + config.outbounds[0].streamSettings.network = "quic" + config.outbounds[0].streamSettings.tcpSettings = nil + config.outbounds[0].streamSettings.tlsSettings?.serverName = tlsSrvName - enum network: String, Codable { - case tcp - case kcp - case ws - case http - case h2 - case domainsocket - case quic - } - - enum security: String, Codable { - case none - case tls - } - - struct TlsSettings: Codable { - var serverName: String? - var alpn: String? - var allowInsecure: Bool? - var allowInsecureCiphers: Bool? - var certificates: TlsCertificates? - - struct TlsCertificates: Codable { - enum usage: String, Codable { - case encipherment - case verify - case issue - } - - var usage: usage? = .encipherment - var certificateFile: String? - var keyFile: String? - var certificate: String? - var key: String? - } - } + return config + } + + func createTcp(outboundIp: String, outboundPort: Int, inboundIp: String, inboundPort: Int, outboundUserId: String) -> V2RayConfig { + var config = createFromTemplate(outboundIp: outboundIp, outboundPort: outboundPort, inboundIp: inboundIp, inboundPort: inboundPort, outboundUserId: outboundUserId) + config.outbounds[0].streamSettings.network = "tcp" + config.outbounds[0].streamSettings.security = "" + config.outbounds[0].streamSettings.quicSettings = nil + config.outbounds[0].streamSettings.tlsSettings = nil - struct TcpSettings: Codable { - var header: Header = Header() - - struct Header: Codable { - var type: String = "none" - var request: Request? - var response: Response? - - struct Request: Codable { - var version: String = "" - var method: String = "" - var path: [String] = [] - var headers: Headers = Headers() - - struct Headers: Codable { - var host: [String] = [] - var userAgent: [String] = [] - var acceptEncoding: [String] = [] - var connection: [String] = [] - var pragma: String = "" - - enum CodingKeys: String, CodingKey { - case host = "Host" - case userAgent = "User-Agent" - case acceptEncoding = "Accept-Encoding" - case connection = "Connection" - case pragma = "Pragma" - } - } - } - - struct Response: Codable { - var version, status, reason: String? - var headers: Headers? - - struct Headers: Codable { - var contentType, transferEncoding, connection: [String]? - var pragma: String? - - enum CodingKeys: String, CodingKey { - case contentType = "Content-Type" - case transferEncoding = "Transfer-Encoding" - case connection = "Connection" - case pragma = "Pragma" - } - } - } - } + return config + } + + func isValid() -> String? { + let port = getLocalPort().port + if port == 0 || inbounds[0].settings.network.isEmpty { + return "inbounds[0].port or inbounds[0].settings.network has invalid value" } - - struct KcpSettings: Codable { - var mtu: Int = 1350 - var tti: Int = 20 - var uplinkCapacity: Int = 50 - var downlinkCapacity: Int = 20 - var congestion: Bool = false - var readBufferSize: Int = 1 - var writeBufferSize: Int = 1 - var header: Header = Header() - - struct Header: Codable { - var type: Type = .none - - enum `Type`: String, Codable { - case none = "none" - case srtp = "srtp" - case utp = "utp" - case wechatVideo = "wechat-video" - case dtls = "dtls" - case wireguard = "wireguard" - } - } + if inbounds[0].settings.address.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { + return "inbounds[0].settings.address is empty" } - - struct WsSettings: Codable { - var path: String = "" - var headers: Header = Header() - - struct Header: Codable { - var host: String = "" - } + if inbounds[0].settings.port == 0 { + return "inbounds[0].settings.port is empty" } - - struct HttpSettings: Codable { - var host: [String] = [""] - var path: String = "" + if outbounds[0].settings.vnext[0].address.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { + return "outbounds[0].settings.vnext[0].address is empty" } - - struct DsSettings: Codable { - var path: String = "" + if outbounds[0].settings.vnext[0].port == 0 { + return "outbounds[0].settings.vnext[0].port is empty" } - - struct Sockopt: Codable { - var mark: Int = 0 - var tcpFastOpen: Bool = false - var tproxy: tproxy = .off // only for linux - - enum tproxy: String, Codable { - case redirect - case tproxy - case off - } + if outbounds[0].settings.vnext[0].users[0].id.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { + return "outbounds[0].settings.vnext[0].users[0].id is empty" } - struct QuicSettings: Codable { - var security: Security = .none - var key: String = "" - var header: Header = Header() - - struct Header: Codable { - var type: Type = .none - - enum `Type`: String, Codable { - case none = "none" - case srtp = "srtp" - case utp = "utp" - case wechatVideo = "wechat-video" - case dtls = "dtls" - case wireguard = "wireguard" - } - } - - enum Security: String, Codable { - case none = "none" - case aes128gcm = "aes-128-gcm" - case chacha20poly1305 = "chacha20-poly1305" - } - } + return nil } } From 34d6bc19c27ae5509e84c26a18b9ca96e1c654a3 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Thu, 24 Aug 2023 09:30:31 +0200 Subject: [PATCH 015/106] feat: update V2RayConfig.swift --- IVPNClient/Models/V2Ray/V2RayConfig.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IVPNClient/Models/V2Ray/V2RayConfig.swift b/IVPNClient/Models/V2Ray/V2RayConfig.swift index aa82de83f..3e9dbfb68 100644 --- a/IVPNClient/Models/V2Ray/V2RayConfig.swift +++ b/IVPNClient/Models/V2Ray/V2RayConfig.swift @@ -141,7 +141,7 @@ struct V2RayConfig: Codable { } } - func createFromTemplate(outboundIp: String, outboundPort: Int, inboundIp: String, inboundPort: Int, outboundUserId: String) -> V2RayConfig { + static func createFromTemplate(outboundIp: String, outboundPort: Int, inboundIp: String, inboundPort: Int, outboundUserId: String) -> V2RayConfig { var config = V2RayConfig.parse(fromJsonFile: "config")! config.inbounds[0].settings.address = inboundIp config.inbounds[0].settings.port = inboundPort @@ -152,7 +152,7 @@ struct V2RayConfig: Codable { return config } - func createQuick(outboundIp: String, outboundPort: Int, inboundIp: String, inboundPort: Int, outboundUserId: String, tlsSrvName: String) -> V2RayConfig { + static func createQuick(outboundIp: String, outboundPort: Int, inboundIp: String, inboundPort: Int, outboundUserId: String, tlsSrvName: String) -> V2RayConfig { var config = createFromTemplate(outboundIp: outboundIp, outboundPort: outboundPort, inboundIp: inboundIp, inboundPort: inboundPort, outboundUserId: outboundUserId) config.outbounds[0].streamSettings.network = "quic" config.outbounds[0].streamSettings.tcpSettings = nil @@ -161,7 +161,7 @@ struct V2RayConfig: Codable { return config } - func createTcp(outboundIp: String, outboundPort: Int, inboundIp: String, inboundPort: Int, outboundUserId: String) -> V2RayConfig { + static func createTcp(outboundIp: String, outboundPort: Int, inboundIp: String, inboundPort: Int, outboundUserId: String) -> V2RayConfig { var config = createFromTemplate(outboundIp: outboundIp, outboundPort: outboundPort, inboundIp: inboundIp, inboundPort: inboundPort, outboundUserId: outboundUserId) config.outbounds[0].streamSettings.network = "tcp" config.outbounds[0].streamSettings.security = "" From 59e19c51c8cb7d1332ce71c41cb74f6c754d8e73 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Sat, 26 Aug 2023 10:41:06 +0200 Subject: [PATCH 016/106] refactor: update AddressType.swift --- IVPNClient/Enums/AddressType.swift | 16 +++++++--------- IVPNClient/Models/WireGuard/CIDRAddress.swift | 2 +- .../Models/WireGuard/WireGuardEndpoint.swift | 4 ++-- UnitTests/Enum/AddressTypeTests.swift | 6 +++--- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/IVPNClient/Enums/AddressType.swift b/IVPNClient/Enums/AddressType.swift index dfd4e784e..2ba6936bd 100644 --- a/IVPNClient/Enums/AddressType.swift +++ b/IVPNClient/Enums/AddressType.swift @@ -21,24 +21,22 @@ // along with the IVPN iOS app. If not, see . // +import Network + enum AddressType { case IPv6 case IPv4 case other - static func validateIpAddress(ipToValidate: String) -> AddressType { - var sin = sockaddr_in() - if ipToValidate.withCString({ cstring in inet_pton(AF_INET, cstring, &sin.sin_addr) }) == 1 { + static func validateIpAddress(_ address: String) -> AddressType { + if let _ = IPv4Address(address) { return .IPv4 - } - - var sin6 = sockaddr_in6() - if ipToValidate.withCString({ cstring in inet_pton(AF_INET6, cstring, &sin6.sin6_addr) }) == 1 { + } else if let _ = IPv6Address(address) { return .IPv6 + } else { + return .other } - - return .other } } diff --git a/IVPNClient/Models/WireGuard/CIDRAddress.swift b/IVPNClient/Models/WireGuard/CIDRAddress.swift index 0c7f3d4c4..1147b9e14 100644 --- a/IVPNClient/Models/WireGuard/CIDRAddress.swift +++ b/IVPNClient/Models/WireGuard/CIDRAddress.swift @@ -58,7 +58,7 @@ struct CIDRAddress { subnetString = "" } - let addressType = AddressType.validateIpAddress(ipToValidate: ipAddress) + let addressType = AddressType.validateIpAddress(ipAddress) guard addressType == .IPv4 || addressType == .IPv6 else { throw CIDRAddressValidationError.invalidIP(ipAddress) diff --git a/IVPNClient/Models/WireGuard/WireGuardEndpoint.swift b/IVPNClient/Models/WireGuard/WireGuardEndpoint.swift index 34ce8b22b..39ebef55c 100644 --- a/IVPNClient/Models/WireGuard/WireGuardEndpoint.swift +++ b/IVPNClient/Models/WireGuard/WireGuardEndpoint.swift @@ -49,7 +49,7 @@ struct WireGuardEndpoint { } hostString = hostString.replacingOccurrences(of: "[", with: "").replacingOccurrences(of: "]", with: "") - var addressType = AddressType.validateIpAddress(ipToValidate: hostString) + var addressType = AddressType.validateIpAddress(hostString) let ipString: String if addressType == .other { @@ -59,7 +59,7 @@ struct WireGuardEndpoint { } ipAddress = String(ipString) - addressType = AddressType.validateIpAddress(ipToValidate: ipAddress) + addressType = AddressType.validateIpAddress(ipAddress) guard addressType == .IPv4 || addressType == .IPv6 else { throw EndpointValidationError.invalidIP(ipAddress) diff --git a/UnitTests/Enum/AddressTypeTests.swift b/UnitTests/Enum/AddressTypeTests.swift index 46effe278..29ed2fee6 100644 --- a/UnitTests/Enum/AddressTypeTests.swift +++ b/UnitTests/Enum/AddressTypeTests.swift @@ -32,9 +32,9 @@ class AddressTypeTests: XCTestCase { let ipAddress2 = "::1" let ipAddress3 = "-" - XCTAssertEqual(AddressType.validateIpAddress(ipToValidate: ipAddress1), .IPv4) - XCTAssertEqual(AddressType.validateIpAddress(ipToValidate: ipAddress2), .IPv6) - XCTAssertEqual(AddressType.validateIpAddress(ipToValidate: ipAddress3), .other) + XCTAssertEqual(AddressType.validateIpAddress(ipAddress1), .IPv4) + XCTAssertEqual(AddressType.validateIpAddress(ipAddress2), .IPv6) + XCTAssertEqual(AddressType.validateIpAddress(ipAddress3), .other) } } From da8c985e08bd6c1a877e1d98d71b882341ea7eee Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Sat, 26 Aug 2023 11:10:17 +0200 Subject: [PATCH 017/106] refactor: update Interface.swift --- IVPNClient.xcodeproj/project.pbxproj | 8 ------- IVPNClient/IVPNClient-Bridging-Header.h | 1 - IVPNClient/Models/WireGuard/Interface.swift | 21 +++++++------------ .../NETunnelProviderProtocol+Ext.swift | 1 - 4 files changed, 7 insertions(+), 24 deletions(-) diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index b0d7e86bd..606914ea4 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -110,7 +110,6 @@ 824B86C926D3D7FB00D0101A /* CIDRAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82F638CB217DC25600410318 /* CIDRAddress.swift */; }; 824B86D226D40E7800D0101A /* FileManager+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824B86AD26D3D16100D0101A /* FileManager+Extension.swift */; }; 824B86D426D40E9700D0101A /* ringlogger.c in Sources */ = {isa = PBXBuildFile; fileRef = 824B86B526D3D16100D0101A /* ringlogger.c */; }; - 824B86DF26D42A4600D0101A /* WireGuardKit in Frameworks */ = {isa = PBXBuildFile; productRef = 824B86DE26D42A4600D0101A /* WireGuardKit */; }; 824B86E126D42A5700D0101A /* WireGuardKit in Frameworks */ = {isa = PBXBuildFile; productRef = 824B86E026D42A5700D0101A /* WireGuardKit */; }; 824BC466240906ED00A61B29 /* VPNStatusViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824BC465240906ED00A61B29 /* VPNStatusViewModel.swift */; }; 82526BEF24123D2900E00880 /* NetworkViewTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82526BEE24123D2900E00880 /* NetworkViewTableCell.swift */; }; @@ -840,7 +839,6 @@ 82EC884129A12D170024CC40 /* ActiveLabel in Frameworks */, 82EC883529A12BD30024CC40 /* JGProgressHUD in Frameworks */, 9CC29DF01E1560990080F799 /* StoreKit.framework in Frameworks */, - 824B86DF26D42A4600D0101A /* WireGuardKit in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1817,7 +1815,6 @@ ); name = IVPNClient; packageProductDependencies = ( - 824B86DE26D42A4600D0101A /* WireGuardKit */, 82968A31298A970500077E0A /* TunnelKitOpenVPN */, 82EC883429A12BD30024CC40 /* JGProgressHUD */, 82EC883729A12C1F0024CC40 /* Reachability */, @@ -3556,11 +3553,6 @@ package = 829F5FC529A13CAE009E1AD3 /* XCRemoteSwiftPackageReference "KeychainAccess" */; productName = KeychainAccess; }; - 824B86DE26D42A4600D0101A /* WireGuardKit */ = { - isa = XCSwiftPackageProductDependency; - package = 824B86DD26D42A4600D0101A /* XCRemoteSwiftPackageReference "wireguard-apple" */; - productName = WireGuardKit; - }; 824B86E026D42A5700D0101A /* WireGuardKit */ = { isa = XCSwiftPackageProductDependency; package = 824B86DD26D42A4600D0101A /* XCRemoteSwiftPackageReference "wireguard-apple" */; diff --git a/IVPNClient/IVPNClient-Bridging-Header.h b/IVPNClient/IVPNClient-Bridging-Header.h index c459cf7b2..69abe91ca 100644 --- a/IVPNClient/IVPNClient-Bridging-Header.h +++ b/IVPNClient/IVPNClient-Bridging-Header.h @@ -1,3 +1,2 @@ -#include "../WireGuardKitC/WireGuardKitC.h" #include "Utilities/Logging/ringlogger.h" #include "liboqs/include/oqs/oqs.h" diff --git a/IVPNClient/Models/WireGuard/Interface.swift b/IVPNClient/Models/WireGuard/Interface.swift index 1af68702e..1398b463b 100644 --- a/IVPNClient/Models/WireGuard/Interface.swift +++ b/IVPNClient/Models/WireGuard/Interface.swift @@ -23,6 +23,7 @@ import Foundation import Network +import CryptoKit struct Interface { @@ -35,14 +36,10 @@ struct Interface { var dns: String? var publicKey: String? { - if let privateKeyString = privateKey, let privateKey = Data(base64Encoded: privateKeyString) { - var publicKey = Data(count: 32) - privateKey.withUnsafeUInt8Bytes { privateKeyBytes in - publicKey.withUnsafeMutableUInt8Bytes { mutableBytes in - curve25519_derive_public_key(mutableBytes, privateKeyBytes) - } - } - return publicKey.base64EncodedString() + if let privateKeyString = privateKey, let privateKey = Data(base64Encoded: privateKeyString), + let privateKeyBytes = try? Curve25519.KeyAgreement.PrivateKey(rawRepresentation: privateKey) { + let publicKey = privateKeyBytes.publicKey + return publicKey.rawRepresentation.base64EncodedString() } else { return nil } @@ -71,12 +68,8 @@ struct Interface { // MARK: - Methods - static func generatePrivateKey() -> String { - var privateKey = Data(count: 32) - privateKey.withUnsafeMutableUInt8Bytes { mutableBytes in - curve25519_generate_private_key(mutableBytes) - } - - return privateKey.base64EncodedString() + let privateKey = Curve25519.KeyAgreement.PrivateKey() + return privateKey.rawRepresentation.base64EncodedString() } static func getAddresses(ipv4: String?, ipv6: String?) -> String { diff --git a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift index 50dc5ce10..ee6698632 100644 --- a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift +++ b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift @@ -27,7 +27,6 @@ import Network import TunnelKitCore import TunnelKitManager import TunnelKitOpenVPN -import WireGuardKit extension NETunnelProviderProtocol { From 031225d364fe2b78b682ec983860c0cfeb6b59ee Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Sat, 26 Aug 2023 11:13:51 +0200 Subject: [PATCH 018/106] refactor: remove openvpn-tunnel-provider/Curve25519 --- IVPNClient.xcodeproj/project.pbxproj | 14 -- openvpn-tunnel-provider/Curve25519/x25519.c | 178 ------------------ openvpn-tunnel-provider/Curve25519/x25519.h | 7 - .../OpenVPNNetworkExtension-Bridging-Header.h | 1 - 4 files changed, 200 deletions(-) delete mode 100644 openvpn-tunnel-provider/Curve25519/x25519.c delete mode 100644 openvpn-tunnel-provider/Curve25519/x25519.h diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index 606914ea4..862070f95 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -321,7 +321,6 @@ 82ED17472A125A4700E7926D /* APIPublicKeyPin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 825E836225A4834200938240 /* APIPublicKeyPin.swift */; }; 82ED17482A125C9100E7926D /* TimerManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824B86C326D3D7B600D0101A /* TimerManager.swift */; }; 82ED174B2A125D0900E7926D /* InterfaceResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 820EA86723223F7900E16B2D /* InterfaceResult.swift */; }; - 82ED17542A1261A000E7926D /* x25519.c in Sources */ = {isa = PBXBuildFile; fileRef = 82ED17512A1261A000E7926D /* x25519.c */; }; 82ED17552A1262BA00E7926D /* Interface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8292E1A82174C11600123538 /* Interface.swift */; }; 82ED17592A1262F800E7926D /* Data+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 828E9C94231E5780001E1FCF /* Data+Ext.swift */; }; 82EEB6C625F9398600915837 /* DNSProtocolType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82EEB6C525F9398600915837 /* DNSProtocolType.swift */; }; @@ -704,8 +703,6 @@ 82E81AE62449C44F00D81FB7 /* PaymentComponentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentComponentView.swift; sourceTree = ""; }; 82EA857921DCF0C300EB0EC9 /* StorageManager+OnDemandRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "StorageManager+OnDemandRuleTests.swift"; sourceTree = ""; }; 82ED17452A1259CB00E7926D /* OpenVPNNetworkExtension-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OpenVPNNetworkExtension-Bridging-Header.h"; sourceTree = ""; }; - 82ED17512A1261A000E7926D /* x25519.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x25519.c; sourceTree = ""; }; - 82ED17522A1261A000E7926D /* x25519.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = x25519.h; sourceTree = ""; }; 82EEB6C525F9398600915837 /* DNSProtocolType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DNSProtocolType.swift; sourceTree = ""; }; 82F189A1225CE8A90038ABA0 /* UIView+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Ext.swift"; sourceTree = ""; }; 82F638C1217DA89000410318 /* AddressType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressType.swift; sourceTree = ""; }; @@ -1565,15 +1562,6 @@ path = View; sourceTree = ""; }; - 82ED17502A12618E00E7926D /* Curve25519 */ = { - isa = PBXGroup; - children = ( - 82ED17512A1261A000E7926D /* x25519.c */, - 82ED17522A1261A000E7926D /* x25519.h */, - ); - path = Curve25519; - sourceTree = ""; - }; 82F81A33224CF36000CB778B /* WireGuard */ = { isa = PBXGroup; children = ( @@ -1617,7 +1605,6 @@ 9C7840A920CD8A8A00335736 /* openvpn-tunnel-provider */ = { isa = PBXGroup; children = ( - 82ED17502A12618E00E7926D /* Curve25519 */, 9C7840AA20CD8A8A00335736 /* PacketTunnelProvider.swift */, 9C7840AC20CD8A8A00335736 /* Info.plist */, 82ED17452A1259CB00E7926D /* OpenVPNNetworkExtension-Bridging-Header.h */, @@ -2205,7 +2192,6 @@ 829F5EB02A570322005919AF /* AntiTrackerDns.swift in Sources */, 82ED17482A125C9100E7926D /* TimerManager.swift in Sources */, 826F7F4323A7AAD200777DB9 /* Array+Ext.swift in Sources */, - 82ED17542A1261A000E7926D /* x25519.c in Sources */, 82ED17402A1258EA00E7926D /* ApiService.swift in Sources */, 82968A36298A98C600077E0A /* KeyChain.swift in Sources */, 82ED17462A125A3000E7926D /* APIAccessManager.swift in Sources */, diff --git a/openvpn-tunnel-provider/Curve25519/x25519.c b/openvpn-tunnel-provider/Curve25519/x25519.c deleted file mode 100644 index 7793299e0..000000000 --- a/openvpn-tunnel-provider/Curve25519/x25519.c +++ /dev/null @@ -1,178 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. - * - * Curve25519 ECDH functions, based on TweetNaCl but cleaned up. - */ - -#include -#include -#include -#include - -#include "x25519.h" - -typedef int64_t fe[16]; - -static inline void carry(fe o) -{ - int i; - - for (i = 0; i < 16; ++i) { - o[(i + 1) % 16] += (i == 15 ? 38 : 1) * (o[i] >> 16); - o[i] &= 0xffff; - } -} - -static inline void cswap(fe p, fe q, int b) -{ - int i; - int64_t t, c = ~(b - 1); - - for (i = 0; i < 16; ++i) { - t = c & (p[i] ^ q[i]); - p[i] ^= t; - q[i] ^= t; - } -} - -static inline void pack(uint8_t *o, const fe n) -{ - int i, j, b; - fe m, t; - - memcpy(t, n, sizeof(t)); - carry(t); - carry(t); - carry(t); - for (j = 0; j < 2; ++j) { - m[0] = t[0] - 0xffed; - for (i = 1; i < 15; ++i) { - m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1); - m[i - 1] &= 0xffff; - } - m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1); - b = (m[15] >> 16) & 1; - m[14] &= 0xffff; - cswap(t, m, 1 - b); - } - for (i = 0; i < 16; ++i) { - o[2 * i] = t[i] & 0xff; - o[2 * i + 1] = t[i] >> 8; - } -} - -static inline void unpack(fe o, const uint8_t *n) -{ - int i; - - for (i = 0; i < 16; ++i) - o[i] = n[2 * i] + ((int64_t)n[2 * i + 1] << 8); - o[15] &= 0x7fff; -} - -static inline void add(fe o, const fe a, const fe b) -{ - int i; - - for (i = 0; i < 16; ++i) - o[i] = a[i] + b[i]; -} - -static inline void subtract(fe o, const fe a, const fe b) -{ - int i; - - for (i = 0; i < 16; ++i) - o[i] = a[i] - b[i]; -} - -static inline void multmod(fe o, const fe a, const fe b) -{ - int i, j; - int64_t t[31] = { 0 }; - - for (i = 0; i < 16; ++i) { - for (j = 0; j < 16; ++j) - t[i + j] += a[i] * b[j]; - } - for (i = 0; i < 15; ++i) - t[i] += 38 * t[i + 16]; - memcpy(o, t, sizeof(fe)); - carry(o); - carry(o); -} - -static inline void invert(fe o, const fe i) -{ - fe c; - int a; - - memcpy(c, i, sizeof(c)); - for (a = 253; a >= 0; --a) { - multmod(c, c, c); - if (a != 2 && a != 4) - multmod(c, c, i); - } - memcpy(o, c, sizeof(fe)); -} - -static void curve25519_shared_secret(uint8_t shared_secret[32], const uint8_t private_key[32], const uint8_t public_key[32]) -{ - static const fe a24 = { 0xdb41, 1 }; - uint8_t z[32]; - int64_t r; - int i; - fe a = { 1 }, b, c = { 0 }, d = { 1 }, e, f, x; - - memcpy(z, private_key, sizeof(z)); - - z[31] = (z[31] & 127) | 64; - z[0] &= 248; - - unpack(x, public_key); - memcpy(b, x, sizeof(b)); - - for (i = 254; i >= 0; --i) { - r = (z[i >> 3] >> (i & 7)) & 1; - cswap(a, b, (int)r); - cswap(c, d, (int)r); - add(e, a, c); - subtract(a, a, c); - add(c, b, d); - subtract(b, b, d); - multmod(d, e, e); - multmod(f, a, a); - multmod(a, c, a); - multmod(c, b, e); - add(e, a, c); - subtract(a, a, c); - multmod(b, a, a); - subtract(c, d, f); - multmod(a, c, a24); - add(a, a, d); - multmod(c, c, a); - multmod(a, d, f); - multmod(d, b, x); - multmod(b, e, e); - cswap(a, b, (int)r); - cswap(c, d, (int)r); - } - invert(c, c); - multmod(a, a, c); - pack(shared_secret, a); -} - -void curve25519_derive_public_key(uint8_t public_key[32], const uint8_t private_key[32]) -{ - static const uint8_t basepoint[32] = { 9 }; - - curve25519_shared_secret(public_key, private_key, basepoint); -} - -void curve25519_generate_private_key(uint8_t private_key[32]) -{ - assert(CCRandomGenerateBytes(private_key, 32) == kCCSuccess); - private_key[31] = (private_key[31] & 127) | 64; - private_key[0] &= 248; -} diff --git a/openvpn-tunnel-provider/Curve25519/x25519.h b/openvpn-tunnel-provider/Curve25519/x25519.h deleted file mode 100644 index 7d8440dd3..000000000 --- a/openvpn-tunnel-provider/Curve25519/x25519.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef X25519_H -#define X25519_H - -void curve25519_derive_public_key(unsigned char public_key[32], const unsigned char private_key[32]); -void curve25519_generate_private_key(unsigned char private_key[32]); - -#endif diff --git a/openvpn-tunnel-provider/OpenVPNNetworkExtension-Bridging-Header.h b/openvpn-tunnel-provider/OpenVPNNetworkExtension-Bridging-Header.h index 08cc28aa4..eec34a060 100644 --- a/openvpn-tunnel-provider/OpenVPNNetworkExtension-Bridging-Header.h +++ b/openvpn-tunnel-provider/OpenVPNNetworkExtension-Bridging-Header.h @@ -1,5 +1,4 @@ #include #include #include -#include "Curve25519/x25519.h" #include "../IVPNClient/liboqs/include/oqs/oqs.h" From 05c09f85d93b563861c8a028f4a224a63c25bc17 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Sat, 26 Aug 2023 11:38:11 +0200 Subject: [PATCH 019/106] build: update build.sh --- .gitmodules | 6 +++--- build.sh | 7 +++++-- vendor/v2ray | 1 + vendor/v2ray-core | 1 - 4 files changed, 9 insertions(+), 6 deletions(-) create mode 160000 vendor/v2ray delete mode 160000 vendor/v2ray-core diff --git a/.gitmodules b/.gitmodules index 86e1c16b4..b4bc19086 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "vendor/v2ray-core"] - path = vendor/v2ray-core - url = https://github.com/v2ray/v2ray-core +[submodule "vendor/v2ray"] + path = vendor/v2ray + url = https://github.com/v2fly/v2ray-core diff --git a/build.sh b/build.sh index d69656151..3ddacc99e 100755 --- a/build.sh +++ b/build.sh @@ -3,14 +3,17 @@ # Exit immediately if a command exits with a non-zero status. set -e +V2RAY_VER=v4.35.0 + echo "=> ⬇️ Clone V2Ray sources.." git submodule update --init echo "=> ⬇️ Get gomobile.." -cd vendor/v2ray-core +cd vendor/v2ray +git checkout ${V2RAY_VER} PATH=$PATH:~/go/bin go get golang.org/x/mobile/cmd/gomobile echo "=> 🍏 Build iOS library.." -gomobile bind --target=ios -o ../../Frameworks/V2Ray.xcframework +gomobile bind -trimpath -ldflags "-s -w" --target=ios -o ../../build/ios/V2Ray.xcframework echo "=> ✅ iOS build completed" diff --git a/vendor/v2ray b/vendor/v2ray new file mode 160000 index 000000000..19d75ac0c --- /dev/null +++ b/vendor/v2ray @@ -0,0 +1 @@ +Subproject commit 19d75ac0c1e31bc652aeb37d76c2a7351ec114c7 diff --git a/vendor/v2ray-core b/vendor/v2ray-core deleted file mode 160000 index d80440f3d..000000000 --- a/vendor/v2ray-core +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d80440f3d57b45c829dbf513306f7adf9a0f3f76 From b32d24a516cc0936ed9c93e1723843b0bc7210ce Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Sat, 26 Aug 2023 11:41:24 +0200 Subject: [PATCH 020/106] build: update build.sh --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 3ddacc99e..6ff31ac76 100755 --- a/build.sh +++ b/build.sh @@ -15,5 +15,5 @@ PATH=$PATH:~/go/bin go get golang.org/x/mobile/cmd/gomobile echo "=> 🍏 Build iOS library.." -gomobile bind -trimpath -ldflags "-s -w" --target=ios -o ../../build/ios/V2Ray.xcframework +gomobile bind -trimpath -ldflags "-s -w" --target=ios -o ../../Frameworks/V2Ray.xcframework echo "=> ✅ iOS build completed" From e206ff28c3d4fc5cf4dd050029a183d322b31e0e Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Sat, 2 Sep 2023 08:39:15 +0200 Subject: [PATCH 021/106] feat: update V2RayCore.swift --- IVPNClient/Models/V2Ray/V2RayCore.swift | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/IVPNClient/Models/V2Ray/V2RayCore.swift b/IVPNClient/Models/V2Ray/V2RayCore.swift index 358190ad3..065b5e708 100644 --- a/IVPNClient/Models/V2Ray/V2RayCore.swift +++ b/IVPNClient/Models/V2Ray/V2RayCore.swift @@ -29,12 +29,11 @@ class V2RayCore { // MARK: - Properties - static let shared = V2RayCore() - var serverPoint: VmessEndpoint? private var core: CoreInstance? // MARK: - Methods - - func start(serverPoint: VmessEndpoint, completion: ((_ error: Error?) -> Void)?) { + func start(completion: ((_ error: Error?) -> Void)?) { if core != nil { try? core?.close() core = nil @@ -49,10 +48,8 @@ class V2RayCore { try config.xxX_Marshal(configData, deterministic: true) core = CoreNew(config, nil) try core?.start() - self.serverPoint = serverPoint } catch let error { startError = error - self.serverPoint = nil } completion?(startError) @@ -64,7 +61,6 @@ class V2RayCore { } try? core?.close() - serverPoint = nil } } From 52b77ddc0032285b90807f74f45f55c8428a9359 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Fri, 8 Sep 2023 11:29:26 +0200 Subject: [PATCH 022/106] feat: update V2RayCore.swift --- IVPNClient/Models/V2Ray/V2RayCore.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/IVPNClient/Models/V2Ray/V2RayCore.swift b/IVPNClient/Models/V2Ray/V2RayCore.swift index 065b5e708..5c59d7323 100644 --- a/IVPNClient/Models/V2Ray/V2RayCore.swift +++ b/IVPNClient/Models/V2Ray/V2RayCore.swift @@ -39,13 +39,10 @@ class V2RayCore { core = nil } - let config = V2RayConfig.parse(fromJsonFile: "config")! - let configData = try? JSONEncoder().encode(config) var startError: Error? = nil do { - let config = CoreConfig.init() - try config.xxX_Marshal(configData, deterministic: true) + let config = CoreConfig() core = CoreNew(config, nil) try core?.start() } catch let error { From e920e57301df2065d51660ee800b49a1e4dbb652 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Sat, 9 Sep 2023 16:50:39 +0200 Subject: [PATCH 023/106] feat: update V2RayCore.swift --- IVPNClient/Models/V2Ray/V2RayCore.swift | 26 +++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/IVPNClient/Models/V2Ray/V2RayCore.swift b/IVPNClient/Models/V2Ray/V2RayCore.swift index 5c59d7323..2a83c4728 100644 --- a/IVPNClient/Models/V2Ray/V2RayCore.swift +++ b/IVPNClient/Models/V2Ray/V2RayCore.swift @@ -30,20 +30,34 @@ class V2RayCore { static let shared = V2RayCore() private var core: CoreInstance? + private let configFile = "config.json" // MARK: - Methods - func start(completion: ((_ error: Error?) -> Void)?) { - if core != nil { - try? core?.close() - core = nil + var startError: Error? = nil + + if let core = core { + do { + try core.close() + self.core = nil + } catch let error { + startError = error + } } - var startError: Error? = nil + var configError: NSError? + let coreConfig = CoreLoadConfigFromJsonFile(configFile, &configError) + if configError != nil { + startError = configError as Error? + } do { - let config = CoreConfig() - core = CoreNew(config, nil) + var initError: NSError? + core = CoreNew(coreConfig, &initError) + if initError != nil { + startError = initError as Error? + } try core?.start() } catch let error { startError = error From f3fb29ffb0c1cccbc20060a8b871b926d9f74c9e Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Mon, 11 Sep 2023 17:50:49 +0200 Subject: [PATCH 024/106] feat: create configv5.json --- IVPNClient.xcodeproj/project.pbxproj | 4 ++++ IVPNClient/Models/V2Ray/V2RayCore.swift | 4 +++- IVPNClient/Models/V2Ray/configv5.json | 31 +++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 IVPNClient/Models/V2Ray/configv5.json diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index 6ca30f7f1..4e0cc0da7 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -114,6 +114,7 @@ 824BC466240906ED00A61B29 /* VPNStatusViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824BC465240906ED00A61B29 /* VPNStatusViewModel.swift */; }; 82526BEF24123D2900E00880 /* NetworkViewTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82526BEE24123D2900E00880 /* NetworkViewTableCell.swift */; }; 8252747E21F1F80400D4B8B5 /* ServerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8252747D21F1F80400D4B8B5 /* ServerViewController.swift */; }; + 825447612AAF482100D710B8 /* configv5.json in Resources */ = {isa = PBXBuildFile; fileRef = 825447602AAF482100D710B8 /* configv5.json */; }; 82555005220ACAAF004763A7 /* VPNServersTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82555004220ACAAF004763A7 /* VPNServersTests.swift */; }; 82589A2B21FB5A580009CC6C /* UIImage+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82589A2A21FB5A580009CC6C /* UIImage+Ext.swift */; }; 825E834F25A327EB00938240 /* CaptchaViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 825E834E25A327EB00938240 /* CaptchaViewController.swift */; }; @@ -553,6 +554,7 @@ 824F56072233FE6F00BCDD5C /* libwg-go.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libwg-go.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 82526BEE24123D2900E00880 /* NetworkViewTableCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkViewTableCell.swift; sourceTree = ""; }; 8252747D21F1F80400D4B8B5 /* ServerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerViewController.swift; sourceTree = ""; }; + 825447602AAF482100D710B8 /* configv5.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = configv5.json; sourceTree = ""; }; 82555004220ACAAF004763A7 /* VPNServersTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNServersTests.swift; sourceTree = ""; }; 8258649C2237A0830081DC4B /* SDCAlertView.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDCAlertView.framework; path = ../Carthage/Build/iOS/SDCAlertView.framework; sourceTree = ""; }; 825864A02237B1060081DC4B /* Bamboo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Bamboo.framework; path = ../Carthage/Build/iOS/Bamboo.framework; sourceTree = ""; }; @@ -942,6 +944,7 @@ 8210A3332A7E2AC9001907E0 /* VmessEndpoint.swift */, 821E35572A95DCD200AEE5C7 /* V2RayCore.swift */, 821E35592A95F77700AEE5C7 /* config.json */, + 825447602AAF482100D710B8 /* configv5.json */, ); path = V2Ray; sourceTree = ""; @@ -2001,6 +2004,7 @@ 9CDDD5B41D9D2F9F00D39924 /* Main.storyboard in Resources */, 9C2833741D9D3EB60024C553 /* Initial.storyboard in Resources */, 826470C42446F67100403A14 /* Signup.storyboard in Resources */, + 825447612AAF482100D710B8 /* configv5.json in Resources */, 82FF0D4223153D1000440E5D /* Colors.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/IVPNClient/Models/V2Ray/V2RayCore.swift b/IVPNClient/Models/V2Ray/V2RayCore.swift index 2a83c4728..89408cd03 100644 --- a/IVPNClient/Models/V2Ray/V2RayCore.swift +++ b/IVPNClient/Models/V2Ray/V2RayCore.swift @@ -30,7 +30,7 @@ class V2RayCore { static let shared = V2RayCore() private var core: CoreInstance? - private let configFile = "config.json" + private let configFile = "configv5.json" // MARK: - Methods - @@ -50,6 +50,8 @@ class V2RayCore { let coreConfig = CoreLoadConfigFromJsonFile(configFile, &configError) if configError != nil { startError = configError as Error? + completion?(startError) + return } do { diff --git a/IVPNClient/Models/V2Ray/configv5.json b/IVPNClient/Models/V2Ray/configv5.json new file mode 100644 index 000000000..c7d85f7fe --- /dev/null +++ b/IVPNClient/Models/V2Ray/configv5.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://github.com/EHfive/v2ray-jsonschema/raw/main/v5-config.schema.json", + "log": { + "access": { + "level": "Debug" + } + }, + "inbounds": [ + { + "protocol": "dokodemo-door", + "port": 16661, + "settings": { + "address": "", + "port": 0, + "networks": "udp" + } + } + ], + "outbounds": [ + { + "tag":"proxy", + "protocol":"vmess", + "sendThrough":"", + "settings": { + "address": "", + "port": 0, + "uuid": "" + } + } + ] +} From 449c6aa203ae36359d5d9de189c69d2a33fdc7c8 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Tue, 12 Sep 2023 17:04:33 +0200 Subject: [PATCH 025/106] feat: update V2RayConfig.swift --- IVPNClient.xcodeproj/project.pbxproj | 4 --- IVPNClient/Models/V2Ray/V2RayConfig.swift | 26 ------------------- IVPNClient/Models/V2Ray/V2RayCore.swift | 2 +- IVPNClient/Models/V2Ray/config.json | 28 -------------------- IVPNClient/Models/V2Ray/configv5.json | 31 ----------------------- 5 files changed, 1 insertion(+), 90 deletions(-) delete mode 100644 IVPNClient/Models/V2Ray/configv5.json diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index 4e0cc0da7..6ca30f7f1 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -114,7 +114,6 @@ 824BC466240906ED00A61B29 /* VPNStatusViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824BC465240906ED00A61B29 /* VPNStatusViewModel.swift */; }; 82526BEF24123D2900E00880 /* NetworkViewTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82526BEE24123D2900E00880 /* NetworkViewTableCell.swift */; }; 8252747E21F1F80400D4B8B5 /* ServerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8252747D21F1F80400D4B8B5 /* ServerViewController.swift */; }; - 825447612AAF482100D710B8 /* configv5.json in Resources */ = {isa = PBXBuildFile; fileRef = 825447602AAF482100D710B8 /* configv5.json */; }; 82555005220ACAAF004763A7 /* VPNServersTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82555004220ACAAF004763A7 /* VPNServersTests.swift */; }; 82589A2B21FB5A580009CC6C /* UIImage+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82589A2A21FB5A580009CC6C /* UIImage+Ext.swift */; }; 825E834F25A327EB00938240 /* CaptchaViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 825E834E25A327EB00938240 /* CaptchaViewController.swift */; }; @@ -554,7 +553,6 @@ 824F56072233FE6F00BCDD5C /* libwg-go.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libwg-go.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 82526BEE24123D2900E00880 /* NetworkViewTableCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkViewTableCell.swift; sourceTree = ""; }; 8252747D21F1F80400D4B8B5 /* ServerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerViewController.swift; sourceTree = ""; }; - 825447602AAF482100D710B8 /* configv5.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = configv5.json; sourceTree = ""; }; 82555004220ACAAF004763A7 /* VPNServersTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNServersTests.swift; sourceTree = ""; }; 8258649C2237A0830081DC4B /* SDCAlertView.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDCAlertView.framework; path = ../Carthage/Build/iOS/SDCAlertView.framework; sourceTree = ""; }; 825864A02237B1060081DC4B /* Bamboo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Bamboo.framework; path = ../Carthage/Build/iOS/Bamboo.framework; sourceTree = ""; }; @@ -944,7 +942,6 @@ 8210A3332A7E2AC9001907E0 /* VmessEndpoint.swift */, 821E35572A95DCD200AEE5C7 /* V2RayCore.swift */, 821E35592A95F77700AEE5C7 /* config.json */, - 825447602AAF482100D710B8 /* configv5.json */, ); path = V2Ray; sourceTree = ""; @@ -2004,7 +2001,6 @@ 9CDDD5B41D9D2F9F00D39924 /* Main.storyboard in Resources */, 9C2833741D9D3EB60024C553 /* Initial.storyboard in Resources */, 826470C42446F67100403A14 /* Signup.storyboard in Resources */, - 825447612AAF482100D710B8 /* configv5.json in Resources */, 82FF0D4223153D1000440E5D /* Colors.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/IVPNClient/Models/V2Ray/V2RayConfig.swift b/IVPNClient/Models/V2Ray/V2RayConfig.swift index 3e9dbfb68..0d5f6b488 100644 --- a/IVPNClient/Models/V2Ray/V2RayConfig.swift +++ b/IVPNClient/Models/V2Ray/V2RayConfig.swift @@ -74,7 +74,6 @@ struct V2RayConfig: Codable { var security: String? var quicSettings: QuicSettings? var tlsSettings: TlsSettings? - var tcpSettings: TcpSettings? struct QuicSettings: Codable { let security: String @@ -89,30 +88,6 @@ struct V2RayConfig: Codable { struct TlsSettings: Codable { var serverName: String } - - struct TcpSettings: Codable { - let header: Header - - struct Header: Codable { - let type: String - let request: Request - - struct Request: Codable { - let version: String - let method: String - let path: [String] - let headers: Headers - - struct Headers: Codable { - let host: [String] - let userAgent: [String] - let acceptEncoding: [String] - let connection: [String] - let pragma: String - } - } - } - } } } @@ -155,7 +130,6 @@ struct V2RayConfig: Codable { static func createQuick(outboundIp: String, outboundPort: Int, inboundIp: String, inboundPort: Int, outboundUserId: String, tlsSrvName: String) -> V2RayConfig { var config = createFromTemplate(outboundIp: outboundIp, outboundPort: outboundPort, inboundIp: inboundIp, inboundPort: inboundPort, outboundUserId: outboundUserId) config.outbounds[0].streamSettings.network = "quic" - config.outbounds[0].streamSettings.tcpSettings = nil config.outbounds[0].streamSettings.tlsSettings?.serverName = tlsSrvName return config diff --git a/IVPNClient/Models/V2Ray/V2RayCore.swift b/IVPNClient/Models/V2Ray/V2RayCore.swift index 89408cd03..31b606fb1 100644 --- a/IVPNClient/Models/V2Ray/V2RayCore.swift +++ b/IVPNClient/Models/V2Ray/V2RayCore.swift @@ -30,7 +30,7 @@ class V2RayCore { static let shared = V2RayCore() private var core: CoreInstance? - private let configFile = "configv5.json" + private let configFile = "config.json" // MARK: - Methods - diff --git a/IVPNClient/Models/V2Ray/config.json b/IVPNClient/Models/V2Ray/config.json index d069697f1..b37e7856c 100644 --- a/IVPNClient/Models/V2Ray/config.json +++ b/IVPNClient/Models/V2Ray/config.json @@ -44,34 +44,6 @@ }, "tlsSettings":{ "serverName":"xb1.gw.inet-telecom.com" - }, - "tcpSettings":{ - "header":{ - "type":"http", - "request":{ - "version":"1.1", - "method":"GET", - "path":[ - "/" - ], - "headers":{ - "Host":[ - "www.inet-telecom.com" - ], - "User-Agent":[ - "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36", - "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46" - ], - "Accept-Encoding":[ - "gzip, deflate" - ], - "Connection":[ - "keep-alive" - ], - "Pragma":"no-cache" - } - } - } } } } diff --git a/IVPNClient/Models/V2Ray/configv5.json b/IVPNClient/Models/V2Ray/configv5.json deleted file mode 100644 index c7d85f7fe..000000000 --- a/IVPNClient/Models/V2Ray/configv5.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "https://github.com/EHfive/v2ray-jsonschema/raw/main/v5-config.schema.json", - "log": { - "access": { - "level": "Debug" - } - }, - "inbounds": [ - { - "protocol": "dokodemo-door", - "port": 16661, - "settings": { - "address": "", - "port": 0, - "networks": "udp" - } - } - ], - "outbounds": [ - { - "tag":"proxy", - "protocol":"vmess", - "sendThrough":"", - "settings": { - "address": "", - "port": 0, - "uuid": "" - } - } - ] -} From e3d30108953d6ea395e48a96496be00f87fcbb3f Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Tue, 12 Sep 2023 17:11:59 +0200 Subject: [PATCH 026/106] feat: update V2RayCore.swift --- IVPNClient.xcodeproj/project.pbxproj | 12 ++---- IVPNClient/Models/V2Ray/V2RayCore.swift | 52 +++++++++---------------- 2 files changed, 22 insertions(+), 42 deletions(-) diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index 6ca30f7f1..fd0c14785 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -53,9 +53,6 @@ 821CA2DF288143470067F70D /* PortRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821CA2DE288143470067F70D /* PortRange.swift */; }; 821E35582A95DCD200AEE5C7 /* V2RayCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821E35572A95DCD200AEE5C7 /* V2RayCore.swift */; }; 821E355A2A95F77700AEE5C7 /* config.json in Resources */ = {isa = PBXBuildFile; fileRef = 821E35592A95F77700AEE5C7 /* config.json */; }; - 821E355F2A96234B00AEE5C7 /* V2Ray.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 821E355E2A96234B00AEE5C7 /* V2Ray.xcframework */; }; - 821E35602A96234B00AEE5C7 /* V2Ray.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 821E355E2A96234B00AEE5C7 /* V2Ray.xcframework */; }; - 821E35612A96234B00AEE5C7 /* V2Ray.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 821E355E2A96234B00AEE5C7 /* V2Ray.xcframework */; }; 821F1C7E21FF544200107311 /* VPNServerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821F1C7D21FF544200107311 /* VPNServerViewModel.swift */; }; 821F604A240D21E3008072D7 /* ControlPanelViewController+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821F6049240D21E3008072D7 /* ControlPanelViewController+Ext.swift */; }; 8221377B2227E75E001E1BF5 /* CustomDNSViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8221377A2227E75E001E1BF5 /* CustomDNSViewController.swift */; }; @@ -114,6 +111,7 @@ 824BC466240906ED00A61B29 /* VPNStatusViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824BC465240906ED00A61B29 /* VPNStatusViewModel.swift */; }; 82526BEF24123D2900E00880 /* NetworkViewTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82526BEE24123D2900E00880 /* NetworkViewTableCell.swift */; }; 8252747E21F1F80400D4B8B5 /* ServerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8252747D21F1F80400D4B8B5 /* ServerViewController.swift */; }; + 8254476A2AB0B5B300D710B8 /* V2RayControl.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 825447692AB0B5B300D710B8 /* V2RayControl.xcframework */; }; 82555005220ACAAF004763A7 /* VPNServersTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82555004220ACAAF004763A7 /* VPNServersTests.swift */; }; 82589A2B21FB5A580009CC6C /* UIImage+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82589A2A21FB5A580009CC6C /* UIImage+Ext.swift */; }; 825E834F25A327EB00938240 /* CaptchaViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 825E834E25A327EB00938240 /* CaptchaViewController.swift */; }; @@ -498,7 +496,6 @@ 821CA2DE288143470067F70D /* PortRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortRange.swift; sourceTree = ""; }; 821E35572A95DCD200AEE5C7 /* V2RayCore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = V2RayCore.swift; sourceTree = ""; }; 821E35592A95F77700AEE5C7 /* config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = config.json; sourceTree = ""; }; - 821E355E2A96234B00AEE5C7 /* V2Ray.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = V2Ray.xcframework; path = Frameworks/V2Ray.xcframework; sourceTree = ""; }; 821F1C7D21FF544200107311 /* VPNServerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNServerViewModel.swift; sourceTree = ""; }; 821F6049240D21E3008072D7 /* ControlPanelViewController+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ControlPanelViewController+Ext.swift"; sourceTree = ""; }; 8221377A2227E75E001E1BF5 /* CustomDNSViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomDNSViewController.swift; sourceTree = ""; }; @@ -553,6 +550,7 @@ 824F56072233FE6F00BCDD5C /* libwg-go.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libwg-go.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 82526BEE24123D2900E00880 /* NetworkViewTableCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkViewTableCell.swift; sourceTree = ""; }; 8252747D21F1F80400D4B8B5 /* ServerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerViewController.swift; sourceTree = ""; }; + 825447692AB0B5B300D710B8 /* V2RayControl.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = V2RayControl.xcframework; path = Frameworks/V2RayControl.xcframework; sourceTree = ""; }; 82555004220ACAAF004763A7 /* VPNServersTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNServersTests.swift; sourceTree = ""; }; 8258649C2237A0830081DC4B /* SDCAlertView.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDCAlertView.framework; path = ../Carthage/Build/iOS/SDCAlertView.framework; sourceTree = ""; }; 825864A02237B1060081DC4B /* Bamboo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Bamboo.framework; path = ../Carthage/Build/iOS/Bamboo.framework; sourceTree = ""; }; @@ -784,7 +782,6 @@ buildActionMask = 2147483647; files = ( 82B6052F21708575004B40E6 /* NetworkExtension.framework in Frameworks */, - 821E35612A96234B00AEE5C7 /* V2Ray.xcframework in Frameworks */, 82BF79622A2F8DDC00061972 /* liboqs.a in Frameworks */, 824B86E126D42A5700D0101A /* WireGuardKit in Frameworks */, 829F5FCB29A13CF2009E1AD3 /* KeychainAccess in Frameworks */, @@ -813,7 +810,6 @@ buildActionMask = 2147483647; files = ( 9CF7E35A20F7A86E008E0EC5 /* NetworkExtension.framework in Frameworks */, - 821E35602A96234B00AEE5C7 /* V2Ray.xcframework in Frameworks */, 829407C12A3DCE9200E6B68E /* liboqs.a in Frameworks */, 82968A34298A970500077E0A /* TunnelKitOpenVPNAppExtension in Frameworks */, 829F5FC929A13CEA009E1AD3 /* KeychainAccess in Frameworks */, @@ -825,11 +821,11 @@ buildActionMask = 2147483647; files = ( 82D598C621A6A5C7000FABDE /* SystemConfiguration.framework in Frameworks */, - 821E355F2A96234B00AEE5C7 /* V2Ray.xcframework in Frameworks */, 9CB2CE311DAF9227007A4D2D /* CoreData.framework in Frameworks */, 9C6942251DD0CBF800F9A801 /* NetworkExtension.framework in Frameworks */, 82486FAD2A277058009B53F4 /* liboqs.a in Frameworks */, 82EC884729A12D510024CC40 /* SnapKit in Frameworks */, + 8254476A2AB0B5B300D710B8 /* V2RayControl.xcframework in Frameworks */, 82EC883B29A12C7D0024CC40 /* SwiftyStoreKit in Frameworks */, 829F5FC729A13CAE009E1AD3 /* KeychainAccess in Frameworks */, 82968A32298A970500077E0A /* TunnelKitOpenVPN in Frameworks */, @@ -847,7 +843,7 @@ 584496306C3B9383149618CE /* Frameworks */ = { isa = PBXGroup; children = ( - 821E355E2A96234B00AEE5C7 /* V2Ray.xcframework */, + 825447692AB0B5B300D710B8 /* V2RayControl.xcframework */, 8294BC8D22A126C900328932 /* TunnelKit.framework */, 8294BC8B22A10F4100328932 /* TunnelKit.framework */, 824F56072233FE6F00BCDD5C /* libwg-go.a */, diff --git a/IVPNClient/Models/V2Ray/V2RayCore.swift b/IVPNClient/Models/V2Ray/V2RayCore.swift index 31b606fb1..f708d4f9a 100644 --- a/IVPNClient/Models/V2Ray/V2RayCore.swift +++ b/IVPNClient/Models/V2Ray/V2RayCore.swift @@ -22,58 +22,42 @@ // import Foundation -import V2Ray +import V2RayControl class V2RayCore { // MARK: - Properties - static let shared = V2RayCore() - private var core: CoreInstance? - private let configFile = "config.json" // MARK: - Methods - - func start(completion: ((_ error: Error?) -> Void)?) { - var startError: Error? = nil + func start() -> Error? { + let _ = close() - if let core = core { - do { - try core.close() - self.core = nil - } catch let error { - startError = error - } - } + var error: Error? = nil + var startError: NSError? - var configError: NSError? - let coreConfig = CoreLoadConfigFromJsonFile(configFile, &configError) - if configError != nil { - startError = configError as Error? - completion?(startError) - return - } + V2rayControlStart("{}", &startError) - do { - var initError: NSError? - core = CoreNew(coreConfig, &initError) - if initError != nil { - startError = initError as Error? - } - try core?.start() - } catch let error { - startError = error + if startError != nil { + error = startError as Error? } - completion?(startError) + return error } - func close() { - guard core != nil else { - return + func close() -> Error? { + var error: Error? = nil + var stopError: NSError? + + V2rayControlStop(&stopError) + + if stopError != nil { + error = stopError as Error? } - try? core?.close() + return error } } From e2d9321f9df21a0ea6c4b61a83cc4a31f8a02129 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Tue, 12 Sep 2023 17:13:37 +0200 Subject: [PATCH 027/106] feat: update .entitlements --- IVPNClient/IVPNClient.entitlements | 2 ++ openvpn-tunnel-provider/openvpn_tunnel_provider.entitlements | 2 ++ .../wireguard_tunnel_provider.entitlements | 2 ++ 3 files changed, 6 insertions(+) diff --git a/IVPNClient/IVPNClient.entitlements b/IVPNClient/IVPNClient.entitlements index 7af37748d..0a88a973e 100644 --- a/IVPNClient/IVPNClient.entitlements +++ b/IVPNClient/IVPNClient.entitlements @@ -10,6 +10,8 @@ NSFileProtectionCompleteUntilFirstUserAuthentication com.apple.developer.networking.networkextension + app-proxy-provider + content-filter-provider packet-tunnel-provider com.apple.developer.networking.vpn.api diff --git a/openvpn-tunnel-provider/openvpn_tunnel_provider.entitlements b/openvpn-tunnel-provider/openvpn_tunnel_provider.entitlements index d2d16571b..fd8928ae9 100644 --- a/openvpn-tunnel-provider/openvpn_tunnel_provider.entitlements +++ b/openvpn-tunnel-provider/openvpn_tunnel_provider.entitlements @@ -4,6 +4,8 @@ com.apple.developer.networking.networkextension + app-proxy-provider + content-filter-provider packet-tunnel-provider com.apple.developer.networking.vpn.api diff --git a/wireguard-tunnel-provider/wireguard_tunnel_provider.entitlements b/wireguard-tunnel-provider/wireguard_tunnel_provider.entitlements index d2d16571b..fd8928ae9 100644 --- a/wireguard-tunnel-provider/wireguard_tunnel_provider.entitlements +++ b/wireguard-tunnel-provider/wireguard_tunnel_provider.entitlements @@ -4,6 +4,8 @@ com.apple.developer.networking.networkextension + app-proxy-provider + content-filter-provider packet-tunnel-provider com.apple.developer.networking.vpn.api From e4d4448c916a3dc541b553f3cd3bcc94c22b945c Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Wed, 13 Sep 2023 11:47:12 +0200 Subject: [PATCH 028/106] feat: update V2RayConfig.swift --- IVPNClient/Models/V2Ray/V2RayConfig.swift | 1 + IVPNClient/Models/V2Ray/config.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/IVPNClient/Models/V2Ray/V2RayConfig.swift b/IVPNClient/Models/V2Ray/V2RayConfig.swift index 0d5f6b488..72acc0039 100644 --- a/IVPNClient/Models/V2Ray/V2RayConfig.swift +++ b/IVPNClient/Models/V2Ray/V2RayConfig.swift @@ -36,6 +36,7 @@ struct V2RayConfig: Codable { } struct Inbound: Codable { + var tag: String var port: String var `protocol`: String var settings: Settings diff --git a/IVPNClient/Models/V2Ray/config.json b/IVPNClient/Models/V2Ray/config.json index b37e7856c..a000eca1d 100644 --- a/IVPNClient/Models/V2Ray/config.json +++ b/IVPNClient/Models/V2Ray/config.json @@ -4,12 +4,13 @@ }, "inbounds":[ { + "tag":"vpn", "port":"16661", "protocol":"dokodemo-door", "settings":{ "address":"", "port":0, - "network":"udp" + "network":"udp,tcp" } } ], From fa2d455b70d6311f54b5424fc2d1f10bda0479b4 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Wed, 13 Sep 2023 11:56:14 +0200 Subject: [PATCH 029/106] feat: add jsonString method in V2RayConfig.swift --- IVPNClient/Models/V2Ray/V2RayConfig.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/IVPNClient/Models/V2Ray/V2RayConfig.swift b/IVPNClient/Models/V2Ray/V2RayConfig.swift index 72acc0039..d785190fa 100644 --- a/IVPNClient/Models/V2Ray/V2RayConfig.swift +++ b/IVPNClient/Models/V2Ray/V2RayConfig.swift @@ -170,4 +170,16 @@ struct V2RayConfig: Codable { return nil } + func jsonString() -> String { + var configString = "{}" + do { + let data = try JSONEncoder().encode(self) + if let json = String(data: data, encoding: .utf8) { + configString = json + } + } catch {} + + return configString + } + } From 4e40a4c44442717b1c1121d1b17bd172e593089f Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Thu, 14 Sep 2023 10:59:15 +0200 Subject: [PATCH 030/106] feat: import V2RayControl.xcframework --- IVPNClient.xcodeproj/project.pbxproj | 20 +--- IVPNClient/Models/V2Ray/VmessEndpoint.swift | 110 -------------------- 2 files changed, 4 insertions(+), 126 deletions(-) delete mode 100644 IVPNClient/Models/V2Ray/VmessEndpoint.swift diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index fd0c14785..5c0053111 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -38,9 +38,6 @@ 820EA86B232242F800E16B2D /* ApiRequestDI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821429BA22FC36100056B8FF /* ApiRequestDI.swift */; }; 820EA86C2322430700E16B2D /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821429B622FC2BE90056B8FF /* Result.swift */; }; 820EA86E232264EC00E16B2D /* SuccessResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 820EA86D232264EC00E16B2D /* SuccessResult.swift */; }; - 8210A3342A7E2ACA001907E0 /* VmessEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8210A3332A7E2AC9001907E0 /* VmessEndpoint.swift */; }; - 8210A3352A7E2ACA001907E0 /* VmessEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8210A3332A7E2AC9001907E0 /* VmessEndpoint.swift */; }; - 8210A3362A7E2ACA001907E0 /* VmessEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8210A3332A7E2AC9001907E0 /* VmessEndpoint.swift */; }; 821429B722FC2BE90056B8FF /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821429B622FC2BE90056B8FF /* Result.swift */; }; 821429B922FC2EA40056B8FF /* ApiService+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821429B822FC2EA40056B8FF /* ApiService+Ext.swift */; }; 821429BB22FC36100056B8FF /* ApiRequestDI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821429BA22FC36100056B8FF /* ApiRequestDI.swift */; }; @@ -73,6 +70,7 @@ 822EE96C215CE0E300BE77F6 /* UserDefaults+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 825A43FC215CCFE70076131F /* UserDefaults+Ext.swift */; }; 8232FBF42240DE19006B81D2 /* ErrorResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8232FBF32240DE19006B81D2 /* ErrorResult.swift */; }; 8232FBF62240E40F006B81D2 /* Error+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8232FBF52240E40F006B81D2 /* Error+Ext.swift */; }; + 8234E0D72AB23E5C0015C9A2 /* V2RayControl.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8234E0D62AB23E5C0015C9A2 /* V2RayControl.xcframework */; }; 82351FCA241FA16600E6E0FD /* InfoAlertViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82351FC9241FA16600E6E0FD /* InfoAlertViewModelTests.swift */; }; 82351FCC241FBC8E00E6E0FD /* VPNStatusViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82351FCB241FBC8E00E6E0FD /* VPNStatusViewModelTests.swift */; }; 82351FCE2420CE6800E6E0FD /* MapMarkerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82351FCD2420CE6800E6E0FD /* MapMarkerView.swift */; }; @@ -94,8 +92,6 @@ 824777EA21A6BC3A001EEFAF /* Network+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824777E621A6BC3A001EEFAF /* Network+CoreDataProperties.swift */; }; 8247A5ED215D037600E8D680 /* UserDefaults+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 825A43FC215CCFE70076131F /* UserDefaults+Ext.swift */; }; 8247C0602A7CF54300A7C02F /* V2RayConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8247C05F2A7CF54300A7C02F /* V2RayConfig.swift */; }; - 8247C0612A7CF54300A7C02F /* V2RayConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8247C05F2A7CF54300A7C02F /* V2RayConfig.swift */; }; - 8247C0622A7CF54300A7C02F /* V2RayConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8247C05F2A7CF54300A7C02F /* V2RayConfig.swift */; }; 8247E1DA22686217006C0C08 /* IAPManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8247E1D922686217006C0C08 /* IAPManager.swift */; }; 8247E1DE22687C28006C0C08 /* ProductIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8247E1DD22687C28006C0C08 /* ProductIdentifier.swift */; }; 82486FAD2A277058009B53F4 /* liboqs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 82486FAC2A277058009B53F4 /* liboqs.a */; }; @@ -111,7 +107,6 @@ 824BC466240906ED00A61B29 /* VPNStatusViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824BC465240906ED00A61B29 /* VPNStatusViewModel.swift */; }; 82526BEF24123D2900E00880 /* NetworkViewTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82526BEE24123D2900E00880 /* NetworkViewTableCell.swift */; }; 8252747E21F1F80400D4B8B5 /* ServerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8252747D21F1F80400D4B8B5 /* ServerViewController.swift */; }; - 8254476A2AB0B5B300D710B8 /* V2RayControl.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 825447692AB0B5B300D710B8 /* V2RayControl.xcframework */; }; 82555005220ACAAF004763A7 /* VPNServersTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82555004220ACAAF004763A7 /* VPNServersTests.swift */; }; 82589A2B21FB5A580009CC6C /* UIImage+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82589A2A21FB5A580009CC6C /* UIImage+Ext.swift */; }; 825E834F25A327EB00938240 /* CaptchaViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 825E834E25A327EB00938240 /* CaptchaViewController.swift */; }; @@ -484,7 +479,6 @@ 8208525B23FD64160008C112 /* MainViewController+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainViewController+Ext.swift"; sourceTree = ""; }; 820EA86723223F7900E16B2D /* InterfaceResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InterfaceResult.swift; sourceTree = ""; }; 820EA86D232264EC00E16B2D /* SuccessResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuccessResult.swift; sourceTree = ""; }; - 8210A3332A7E2AC9001907E0 /* VmessEndpoint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VmessEndpoint.swift; sourceTree = ""; }; 821429B622FC2BE90056B8FF /* Result.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Result.swift; sourceTree = ""; }; 821429B822FC2EA40056B8FF /* ApiService+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ApiService+Ext.swift"; sourceTree = ""; }; 821429BA22FC36100056B8FF /* ApiRequestDI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiRequestDI.swift; sourceTree = ""; }; @@ -509,6 +503,7 @@ 822BC6892A7CF3A700C733DF /* Decodable+Ext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Decodable+Ext.swift"; sourceTree = ""; }; 8232FBF32240DE19006B81D2 /* ErrorResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorResult.swift; sourceTree = ""; }; 8232FBF52240E40F006B81D2 /* Error+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Error+Ext.swift"; sourceTree = ""; }; + 8234E0D62AB23E5C0015C9A2 /* V2RayControl.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = V2RayControl.xcframework; path = Frameworks/V2RayControl.xcframework; sourceTree = ""; }; 82351FC9241FA16600E6E0FD /* InfoAlertViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoAlertViewModelTests.swift; sourceTree = ""; }; 82351FCB241FBC8E00E6E0FD /* VPNStatusViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNStatusViewModelTests.swift; sourceTree = ""; }; 82351FCD2420CE6800E6E0FD /* MapMarkerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapMarkerView.swift; sourceTree = ""; }; @@ -550,7 +545,6 @@ 824F56072233FE6F00BCDD5C /* libwg-go.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libwg-go.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 82526BEE24123D2900E00880 /* NetworkViewTableCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkViewTableCell.swift; sourceTree = ""; }; 8252747D21F1F80400D4B8B5 /* ServerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerViewController.swift; sourceTree = ""; }; - 825447692AB0B5B300D710B8 /* V2RayControl.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = V2RayControl.xcframework; path = Frameworks/V2RayControl.xcframework; sourceTree = ""; }; 82555004220ACAAF004763A7 /* VPNServersTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNServersTests.swift; sourceTree = ""; }; 8258649C2237A0830081DC4B /* SDCAlertView.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDCAlertView.framework; path = ../Carthage/Build/iOS/SDCAlertView.framework; sourceTree = ""; }; 825864A02237B1060081DC4B /* Bamboo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Bamboo.framework; path = ../Carthage/Build/iOS/Bamboo.framework; sourceTree = ""; }; @@ -820,12 +814,12 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 8234E0D72AB23E5C0015C9A2 /* V2RayControl.xcframework in Frameworks */, 82D598C621A6A5C7000FABDE /* SystemConfiguration.framework in Frameworks */, 9CB2CE311DAF9227007A4D2D /* CoreData.framework in Frameworks */, 9C6942251DD0CBF800F9A801 /* NetworkExtension.framework in Frameworks */, 82486FAD2A277058009B53F4 /* liboqs.a in Frameworks */, 82EC884729A12D510024CC40 /* SnapKit in Frameworks */, - 8254476A2AB0B5B300D710B8 /* V2RayControl.xcframework in Frameworks */, 82EC883B29A12C7D0024CC40 /* SwiftyStoreKit in Frameworks */, 829F5FC729A13CAE009E1AD3 /* KeychainAccess in Frameworks */, 82968A32298A970500077E0A /* TunnelKitOpenVPN in Frameworks */, @@ -843,7 +837,7 @@ 584496306C3B9383149618CE /* Frameworks */ = { isa = PBXGroup; children = ( - 825447692AB0B5B300D710B8 /* V2RayControl.xcframework */, + 8234E0D62AB23E5C0015C9A2 /* V2RayControl.xcframework */, 8294BC8D22A126C900328932 /* TunnelKit.framework */, 8294BC8B22A10F4100328932 /* TunnelKit.framework */, 824F56072233FE6F00BCDD5C /* libwg-go.a */, @@ -935,7 +929,6 @@ isa = PBXGroup; children = ( 8247C05F2A7CF54300A7C02F /* V2RayConfig.swift */, - 8210A3332A7E2AC9001907E0 /* VmessEndpoint.swift */, 821E35572A95DCD200AEE5C7 /* V2RayCore.swift */, 821E35592A95F77700AEE5C7 /* config.json */, ); @@ -2075,8 +2068,6 @@ 82E7169A2181E96F00D6B7C2 /* OpenVPNProtocol.swift in Sources */, 8205352A2302BEA3007BDD58 /* Array+Ext.swift in Sources */, 82E716882181E8E100D6B7C2 /* ProviderConfigurationKeys.swift in Sources */, - 8210A3362A7E2ACA001907E0 /* VmessEndpoint.swift in Sources */, - 8247C0622A7CF54300A7C02F /* V2RayConfig.swift in Sources */, 82F638C5217DA89000410318 /* AddressType.swift in Sources */, 82EEB6DB25F961BC00915837 /* URL+Ext.swift in Sources */, 822919712182EB1C00978BBA /* String+Ext.swift in Sources */, @@ -2198,10 +2189,8 @@ 829407C02A3DCC5500E6B68E /* KemHelper.swift in Sources */, 82ED17472A125A4700E7926D /* APIPublicKeyPin.swift in Sources */, 827123172A3C758100882336 /* AppKeyManager.swift in Sources */, - 8247C0612A7CF54300A7C02F /* V2RayConfig.swift in Sources */, 82ED17552A1262BA00E7926D /* Interface.swift in Sources */, 82E716812181E8AF00D6B7C2 /* TunnelType.swift in Sources */, - 8210A3352A7E2ACA001907E0 /* VmessEndpoint.swift in Sources */, 82A208C121BAAC6C00C9AD44 /* Config.swift in Sources */, 82ED174B2A125D0900E7926D /* InterfaceResult.swift in Sources */, ); @@ -2320,7 +2309,6 @@ 82A160BB221C4E2000730577 /* Server+CoreDataProperties.swift in Sources */, 8270753622AFC5B90067C323 /* StringProtocol+Ext.swift in Sources */, 82526BEF24123D2900E00880 /* NetworkViewTableCell.swift in Sources */, - 8210A3342A7E2ACA001907E0 /* VmessEndpoint.swift in Sources */, 82DEF021244714F000CCB5CD /* ScannerView.swift in Sources */, 826FBDA52461848A00B9E464 /* ServiceDuration.swift in Sources */, 9CB2CE411DB2594A007A4D2D /* VPNServerList.swift in Sources */, diff --git a/IVPNClient/Models/V2Ray/VmessEndpoint.swift b/IVPNClient/Models/V2Ray/VmessEndpoint.swift deleted file mode 100644 index 590999fb2..000000000 --- a/IVPNClient/Models/V2Ray/VmessEndpoint.swift +++ /dev/null @@ -1,110 +0,0 @@ -// -// VmessEndpoint.swift -// IVPN iOS app -// https://github.com/ivpn/ios-app -// -// Created by Juraj Hilje on 2023-08-05. -// Copyright (c) 2023 IVPN Limited. -// -// This file is part of the IVPN iOS app. -// -// The IVPN iOS app 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. -// -// The IVPN iOS app 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 the IVPN iOS app. If not, see . -// - -import Foundation - -struct VmessEndpoint: Codable, Hashable { - - var url: String? = nil - var path: String? = nil - var info: Dictionary = [:] - - enum InfoKey: String, CodingKey { - case address = "add" - case port - case type - case host - case aid - case uuid = "id" - case tls - case net - case ps - } - - enum CodingKeys: String, CodingKey { - case url - case path - case info - } - - static func generatePoints(with vmessUrls:[String]) -> [VmessEndpoint] { - var array: [VmessEndpoint] = Array() - for url in vmessUrls { - if url.count > 0 && url.hasPrefix("vmess://") { - array.append(VmessEndpoint.init(url)) - } - } - return array - } - - func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - url != nil ? try container.encode(url, forKey: .url) : nil - path != nil ? try container.encode(path, forKey: .path) : nil - - if !info.isEmpty, let jsonData = try? JSONSerialization.data(withJSONObject: info) { - try container.encode(jsonData, forKey: .info) - } - } - - init(from decoder: Decoder) throws { - let values = try decoder.container(keyedBy: CodingKeys.self) - url = (values.contains(.url) == true) ? try values.decode(String.self, forKey: .url) : nil - path = (values.contains(.path) == true) ? try values.decode(String.self, forKey: .path) : nil - - if values.contains(.info), let jsonData = try? values.decode(Data.self, forKey: .info) { - info = (try? JSONSerialization.jsonObject(with: jsonData) as? [String: Any]) ?? [String: Any]() - } else { - info = [String: Any]() - } - } - - init(_ url: String?) { - self.url = url?.replacingOccurrences(of: "\r", with: "") - self.path = self.url?.replacingOccurrences(of: "vmess://", with: "") - - guard let path = self.path else { - return - } - - guard let base64Data = Data.init(base64Encoded: path) else { - return - } - - guard let dic = try? JSONSerialization.jsonObject(with: base64Data, options: [.allowFragments, .fragmentsAllowed, .mutableContainers, .mutableLeaves]) else { - return - } - - self.info = dic as! Dictionary - } - - static func == (lhs: VmessEndpoint, rhs: VmessEndpoint) -> Bool { - return lhs.url == rhs.url - } - - func hash(into hasher: inout Hasher) { - hasher.combine(url) - } - -} - From 28821b9de8c46660a9c35ac69157f14e1d2b8fd1 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Fri, 15 Sep 2023 13:50:17 +0200 Subject: [PATCH 031/106] feat: update V2RayCore.swift --- IVPNClient/Models/V2Ray/V2RayCore.swift | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/IVPNClient/Models/V2Ray/V2RayCore.swift b/IVPNClient/Models/V2Ray/V2RayCore.swift index f708d4f9a..cc0e083a0 100644 --- a/IVPNClient/Models/V2Ray/V2RayCore.swift +++ b/IVPNClient/Models/V2Ray/V2RayCore.swift @@ -29,17 +29,16 @@ class V2RayCore { // MARK: - Properties - static let shared = V2RayCore() + var instance: V2rayControlInstance? // MARK: - Methods - func start() -> Error? { let _ = close() - var error: Error? = nil - var startError: NSError? - - V2rayControlStart("{}", &startError) + var startError: NSError? + instance = V2rayControlStart("{}", &startError) if startError != nil { error = startError as Error? } @@ -49,14 +48,15 @@ class V2RayCore { func close() -> Error? { var error: Error? = nil - var stopError: NSError? - V2rayControlStop(&stopError) - - if stopError != nil { - error = stopError as Error? + if let instance = instance { + var stopError: NSError? + V2rayControlStop(instance, &stopError) + if stopError != nil { + error = stopError as Error? + } } - + return error } From f47049232afa91847bc40ee16807c33abb3adb3b Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Mon, 18 Sep 2023 12:27:16 +0200 Subject: [PATCH 032/106] feat: add TcpSettings in V2RayConfig.swift --- IVPNClient/Models/V2Ray/V2RayConfig.swift | 34 +++++++++++++++++++++++ IVPNClient/Models/V2Ray/config.json | 17 ++++++++++++ 2 files changed, 51 insertions(+) diff --git a/IVPNClient/Models/V2Ray/V2RayConfig.swift b/IVPNClient/Models/V2Ray/V2RayConfig.swift index d785190fa..5f9dd3540 100644 --- a/IVPNClient/Models/V2Ray/V2RayConfig.swift +++ b/IVPNClient/Models/V2Ray/V2RayConfig.swift @@ -75,6 +75,7 @@ struct V2RayConfig: Codable { var security: String? var quicSettings: QuicSettings? var tlsSettings: TlsSettings? + var tcpSettings: TcpSettings? struct QuicSettings: Codable { let security: String @@ -89,6 +90,38 @@ struct V2RayConfig: Codable { struct TlsSettings: Codable { var serverName: String } + + struct TcpSettings: Codable { + let header: Header + + struct Header: Codable { + let type: String + let request: Request + + struct Request: Codable { + let version: String + let method: String + let path: [String] + let headers: Headers + + struct Headers: Codable { + let host: [String] + let userAgent: [String] + let acceptEncoding: [String] + let connection: [String] + let pragma: String + + enum CodingKeys : String, CodingKey { + case host = "Host" + case userAgent = "User-Agent" + case acceptEncoding = "Accept-Encoding" + case connection = "Connection" + case pragma = "Pragma" + } + } + } + } + } } } @@ -131,6 +164,7 @@ struct V2RayConfig: Codable { static func createQuick(outboundIp: String, outboundPort: Int, inboundIp: String, inboundPort: Int, outboundUserId: String, tlsSrvName: String) -> V2RayConfig { var config = createFromTemplate(outboundIp: outboundIp, outboundPort: outboundPort, inboundIp: inboundIp, inboundPort: inboundPort, outboundUserId: outboundUserId) config.outbounds[0].streamSettings.network = "quic" + config.outbounds[0].streamSettings.tcpSettings = nil config.outbounds[0].streamSettings.tlsSettings?.serverName = tlsSrvName return config diff --git a/IVPNClient/Models/V2Ray/config.json b/IVPNClient/Models/V2Ray/config.json index a000eca1d..58292b615 100644 --- a/IVPNClient/Models/V2Ray/config.json +++ b/IVPNClient/Models/V2Ray/config.json @@ -45,6 +45,23 @@ }, "tlsSettings":{ "serverName":"xb1.gw.inet-telecom.com" + }, + "tcpSettings":{ + "header":{ + "type":"http", + "request":{ + "version":"1.1", + "method":"GET", + "path":["/"], + "headers":{ + "Host":["www.inet-telecom.com"], + "User-Agent":["Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36", "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46"], + "Accept-Encoding":["gzip, deflate"], + "Connection":["keep-alive"], + "Pragma":"no-cache" + } + } + } } } } From b2ffbdab1b71cdab992a5d079087a2ac43d8677e Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Mon, 18 Sep 2023 12:29:03 +0200 Subject: [PATCH 033/106] feat: add v2ray property in Host.swift --- IVPNClient/Models/Host.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/IVPNClient/Models/Host.swift b/IVPNClient/Models/Host.swift index 326f0485d..40ab6ffe8 100644 --- a/IVPNClient/Models/Host.swift +++ b/IVPNClient/Models/Host.swift @@ -37,6 +37,7 @@ struct Host: Codable { var ipv6: IPv6? var multihopPort: Int var load: Double + var v2ray: String func localIPAddress() -> String { if let range = localIP.range(of: "/", options: .backwards, range: nil, locale: nil) { From 69fa660e89bddb09d97df0c857e3eefd2068c0e0 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Mon, 18 Sep 2023 13:04:14 +0200 Subject: [PATCH 034/106] feat: create V2RayPorts.swift --- IVPNClient.xcodeproj/project.pbxproj | 4 ++ IVPNClient/Models/V2Ray/V2RayPorts.swift | 53 +++++++++++++++++++ IVPNClient/Models/VPNServerList.swift | 18 ++++++- .../Extensions/UserDefaults+Ext.swift | 2 + 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 IVPNClient/Models/V2Ray/V2RayPorts.swift diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index 5c0053111..e59c44894 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -75,6 +75,7 @@ 82351FCC241FBC8E00E6E0FD /* VPNStatusViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82351FCB241FBC8E00E6E0FD /* VPNStatusViewModelTests.swift */; }; 82351FCE2420CE6800E6E0FD /* MapMarkerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82351FCD2420CE6800E6E0FD /* MapMarkerView.swift */; }; 82351FD224222F7700E6E0FD /* ConnectionInfoPopupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82351FD124222F7700E6E0FD /* ConnectionInfoPopupView.swift */; }; + 82365E7F2AB86020006434C3 /* V2RayPorts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82365E7E2AB86020006434C3 /* V2RayPorts.swift */; }; 823ACC292626E69F006F69AB /* GeoLookupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823ACC282626E69F006F69AB /* GeoLookupTests.swift */; }; 823ACC312626FF3E006F69AB /* IpProtocolView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823ACC302626FF3E006F69AB /* IpProtocolView.swift */; }; 823ACC3926270330006F69AB /* ConnectionInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823ACC3826270330006F69AB /* ConnectionInfoView.swift */; }; @@ -508,6 +509,7 @@ 82351FCB241FBC8E00E6E0FD /* VPNStatusViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNStatusViewModelTests.swift; sourceTree = ""; }; 82351FCD2420CE6800E6E0FD /* MapMarkerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapMarkerView.swift; sourceTree = ""; }; 82351FD124222F7700E6E0FD /* ConnectionInfoPopupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionInfoPopupView.swift; sourceTree = ""; }; + 82365E7E2AB86020006434C3 /* V2RayPorts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = V2RayPorts.swift; sourceTree = ""; }; 823ACC282626E69F006F69AB /* GeoLookupTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeoLookupTests.swift; sourceTree = ""; }; 823ACC302626FF3E006F69AB /* IpProtocolView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IpProtocolView.swift; sourceTree = ""; }; 823ACC3826270330006F69AB /* ConnectionInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionInfoView.swift; sourceTree = ""; }; @@ -929,6 +931,7 @@ isa = PBXGroup; children = ( 8247C05F2A7CF54300A7C02F /* V2RayConfig.swift */, + 82365E7E2AB86020006434C3 /* V2RayPorts.swift */, 821E35572A95DCD200AEE5C7 /* V2RayCore.swift */, 821E35592A95F77700AEE5C7 /* config.json */, ); @@ -2284,6 +2287,7 @@ 822563922431E03A00AE7F8D /* AccountView.swift in Sources */, 9CBFF02C21021D2100FE1757 /* ConnectionManager.swift in Sources */, 82D598C821A6ADF1000FABDE /* NetworkType.swift in Sources */, + 82365E7F2AB86020006434C3 /* V2RayPorts.swift in Sources */, 9CC29DF81E1D59E90080F799 /* Alerts+Ext.swift in Sources */, 9CB2CE1F1DAA5258007A4D2D /* Authentication.swift in Sources */, 82DAB37B2457013900302F4C /* Service.swift in Sources */, diff --git a/IVPNClient/Models/V2Ray/V2RayPorts.swift b/IVPNClient/Models/V2Ray/V2RayPorts.swift new file mode 100644 index 000000000..e7ba1c1b1 --- /dev/null +++ b/IVPNClient/Models/V2Ray/V2RayPorts.swift @@ -0,0 +1,53 @@ +// +// V2RayPorts.swift +// IVPN iOS app +// https://github.com/ivpn/ios-app +// +// Created by Juraj Hilje on 2023-09-18. +// Copyright (c) 2023 IVPN Limited. +// +// This file is part of the IVPN iOS app. +// +// The IVPN iOS app 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. +// +// The IVPN iOS app 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 the IVPN iOS app. If not, see . +// + +import Foundation + +struct V2RayPorts: Codable { + + let id: String + let openvpn: [V2RayPort] + let wireguard: [V2RayPort] + + func save() { + if let encoded = try? JSONEncoder().encode(self) { + UserDefaults.shared.set(encoded, forKey: UserDefaults.Key.v2RayPorts) + } + } + + static func load() -> V2RayPorts? { + if let saved = UserDefaults.shared.object(forKey: UserDefaults.Key.v2RayPorts) as? Data { + if let loaded = try? JSONDecoder().decode(V2RayPorts.self, from: saved) { + return loaded + } + } + + return nil + } + +} + +struct V2RayPort: Codable { + let type: String + let port: Int +} diff --git a/IVPNClient/Models/VPNServerList.swift b/IVPNClient/Models/VPNServerList.swift index d81501573..18e0c458e 100644 --- a/IVPNClient/Models/VPNServerList.swift +++ b/IVPNClient/Models/VPNServerList.swift @@ -190,6 +190,7 @@ class VPNServerList { portRanges.append(PortRange(tunnelType: "OpenVPN", protocolType: "TCP", ranges: tcpRanges)) } } + if let wireguard = portsObj["wireguard"] as? [[String: Any]] { var ranges = [CountableClosedRange]() for port in wireguard { @@ -206,6 +207,20 @@ class VPNServerList { portRanges.append(PortRange(tunnelType: "WireGuard", protocolType: "UDP", ranges: ranges)) } } + + if let v2ray = portsObj["v2ray"] as? [String: Any] { + if let wireguard = v2ray["wireguard"] as? [[String: Any]] { + var ports = [V2RayPort]() + for port in wireguard { + let type = port["type"] as? String ?? "" + let port = port["port"] as? Int ?? 0 + ports.append(V2RayPort(type: type, port: port)) + } + let id = v2ray["id"] as? String ?? "" + let v2rayPorts = V2RayPorts(id: id, openvpn: [], wireguard: ports) + v2rayPorts.save() + } + } } } } @@ -399,7 +414,8 @@ class VPNServerList { publicKey: host["public_key"] as? String ?? "", localIP: host["local_ip"] as? String ?? "", multihopPort: host["multihop_port"] as? Int ?? 0, - load: host["load"] as? Double ?? 0 + load: host["load"] as? Double ?? 0, + v2ray: host["v2ray"] as? String ?? "" ) if let ipv6 = host["ipv6"] as? [String: Any] { diff --git a/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift b/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift index af852de46..eb710af2d 100644 --- a/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift +++ b/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift @@ -90,6 +90,7 @@ extension UserDefaults { static let isLoggedIn = "isLoggedIn" static let antiTrackerDns = "antiTrackerDns" static let disableLanAccess = "disableLanAccess" + static let v2RayPorts = "v2RayPorts" } @objc dynamic var wireguardTunnelProviderError: String { @@ -276,6 +277,7 @@ extension UserDefaults { shared.removeObject(forKey: Key.isLoggedIn) shared.removeObject(forKey: Key.antiTrackerDns) shared.removeObject(forKey: Key.disableLanAccess) + shared.removeObject(forKey: Key.v2RayPorts) standard.removeObject(forKey: Key.serviceStatus) standard.removeObject(forKey: Key.selectedHost) standard.removeObject(forKey: Key.selectedExitHost) From 14eae4b0267cc7206d3a9f806178d4d4bc55426f Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Mon, 18 Sep 2023 14:13:41 +0200 Subject: [PATCH 035/106] feat: add makeConfig method in V2RayCore.swift --- IVPNClient/Config/Config.swift | 5 +++++ IVPNClient/Models/V2Ray/V2RayCore.swift | 23 ++++++++++++++++++++++- IVPNClient/Models/V2Ray/V2RayPorts.swift | 9 ++++++++- IVPNClient/Models/VPNServerList.swift | 3 ++- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/IVPNClient/Config/Config.swift b/IVPNClient/Config/Config.swift index f992a1b9d..59d11fb73 100644 --- a/IVPNClient/Config/Config.swift +++ b/IVPNClient/Config/Config.swift @@ -80,6 +80,11 @@ struct Config { static let wgKeyExpirationDays = 30 static let wgKeyRegenerationRate = 1 + // MARK: V2Ray + + static let v2rayHost = "127.0.0.1" + static let v2rayPort = 16661 + // MARK: ENV variables static var Environment: String { diff --git a/IVPNClient/Models/V2Ray/V2RayCore.swift b/IVPNClient/Models/V2Ray/V2RayCore.swift index cc0e083a0..0f3185ac0 100644 --- a/IVPNClient/Models/V2Ray/V2RayCore.swift +++ b/IVPNClient/Models/V2Ray/V2RayCore.swift @@ -37,8 +37,12 @@ class V2RayCore { let _ = close() var error: Error? = nil + guard let config = makeConfig() else { + return NSError(domain: "", code: 99, userInfo: [NSLocalizedDescriptionKey: "V2Ray configuration cannot be loaded"]) + } + var startError: NSError? - instance = V2rayControlStart("{}", &startError) + instance = V2rayControlStart(config.jsonString(), &startError) if startError != nil { error = startError as Error? } @@ -60,4 +64,21 @@ class V2RayCore { return error } + func makeConfig() -> V2RayConfig? { + guard let v2rayPorts = V2RayPorts.load() else { + return nil + } + + let host = v2rayPorts.host + let outboundIp = host.v2ray + let outboundPort = v2rayPorts.port + let inboundIp = host.host + let inboundPort = v2rayPorts.wireguard.first?.port ?? 0 + let outboundUserId = v2rayPorts.id + let tlsSrvName = host.dnsName.replacingOccurrences(of: "ivpn.net", with: "inet-telecom.com") + let config = V2RayConfig.createQuick(outboundIp: outboundIp, outboundPort: outboundPort, inboundIp: inboundIp, inboundPort: inboundPort, outboundUserId: outboundUserId, tlsSrvName: tlsSrvName) + + return config + } + } diff --git a/IVPNClient/Models/V2Ray/V2RayPorts.swift b/IVPNClient/Models/V2Ray/V2RayPorts.swift index e7ba1c1b1..0f68d1851 100644 --- a/IVPNClient/Models/V2Ray/V2RayPorts.swift +++ b/IVPNClient/Models/V2Ray/V2RayPorts.swift @@ -26,7 +26,8 @@ import Foundation struct V2RayPorts: Codable { let id: String - let openvpn: [V2RayPort] + var port: Int + var host: V2RayHost let wireguard: [V2RayPort] func save() { @@ -51,3 +52,9 @@ struct V2RayPort: Codable { let type: String let port: Int } + +struct V2RayHost: Codable { + let host: String + let dnsName: String + let v2ray: String +} diff --git a/IVPNClient/Models/VPNServerList.swift b/IVPNClient/Models/VPNServerList.swift index 18e0c458e..bc726ea80 100644 --- a/IVPNClient/Models/VPNServerList.swift +++ b/IVPNClient/Models/VPNServerList.swift @@ -217,7 +217,8 @@ class VPNServerList { ports.append(V2RayPort(type: type, port: port)) } let id = v2ray["id"] as? String ?? "" - let v2rayPorts = V2RayPorts(id: id, openvpn: [], wireguard: ports) + let v2rayHost = V2RayHost(host: "", dnsName: "", v2ray: "") + let v2rayPorts = V2RayPorts(id: id, port: 0, host: v2rayHost, wireguard: ports) v2rayPorts.save() } } From 84abb80d978159a54c3b3e059a5c0e31066dfa24 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Mon, 18 Sep 2023 15:26:53 +0200 Subject: [PATCH 036/106] feat: update V2RayConfig.swift and config.json --- IVPNClient/Models/V2Ray/V2RayConfig.swift | 1 + IVPNClient/Models/V2Ray/config.json | 1 + 2 files changed, 2 insertions(+) diff --git a/IVPNClient/Models/V2Ray/V2RayConfig.swift b/IVPNClient/Models/V2Ray/V2RayConfig.swift index 5f9dd3540..217a1a788 100644 --- a/IVPNClient/Models/V2Ray/V2RayConfig.swift +++ b/IVPNClient/Models/V2Ray/V2RayConfig.swift @@ -38,6 +38,7 @@ struct V2RayConfig: Codable { struct Inbound: Codable { var tag: String var port: String + var listen: String var `protocol`: String var settings: Settings diff --git a/IVPNClient/Models/V2Ray/config.json b/IVPNClient/Models/V2Ray/config.json index 58292b615..335fd70ab 100644 --- a/IVPNClient/Models/V2Ray/config.json +++ b/IVPNClient/Models/V2Ray/config.json @@ -6,6 +6,7 @@ { "tag":"vpn", "port":"16661", + "listen":"127.0.0.1", "protocol":"dokodemo-door", "settings":{ "address":"", From 069969265dc5fe42ae553838bc64732a04bf9a49 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Mon, 18 Sep 2023 17:36:20 +0200 Subject: [PATCH 037/106] feat: update NETunnelProviderProtocol+Ext.swift --- .../Extensions/NETunnelProviderProtocol+Ext.swift | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift index 31b32404e..56b2212a0 100644 --- a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift +++ b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift @@ -126,10 +126,13 @@ extension NETunnelProviderProtocol { var publicKey = host.publicKey let port = getPort(settings: settings) var endpoint = Peer.endpoint(host: host.host, port: port) + var v2rayHost = host + var v2rayPort = port if UserDefaults.shared.isMultiHop, Application.shared.serviceStatus.isEnabled(capability: .multihop), let exitHost = getExitHost() { publicKey = exitHost.publicKey endpoint = Peer.endpoint(host: host.host, port: exitHost.multihopPort) + v2rayHost = exitHost } if let ipv6 = host.ipv6, UserDefaults.shared.isIPv6 { @@ -138,6 +141,16 @@ extension NETunnelProviderProtocol { KeyChain.wgIpv6Host = ipv6.localIP } + // If V2Ray is enabled + if (true) { + endpoint = Peer.endpoint(host: Config.v2rayHost, port: Config.v2rayPort) + if var v2rayPorts = V2RayPorts.load() { + v2rayPorts.port = v2rayPort + v2rayPorts.host = V2RayHost(host: v2rayHost.host, dnsName: v2rayHost.dnsName, v2ray: v2rayHost.v2ray) + v2rayPorts.save() + } + } + let peer = Peer( publicKey: publicKey, presharedKey: KeyChain.wgPresharedKey, From 8bb182f593ec98dc5cefb9978760bf10c4e02cb1 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Mon, 18 Sep 2023 17:38:38 +0200 Subject: [PATCH 038/106] feat: update NETunnelProviderProtocol+Ext.swift --- .../Utilities/Extensions/NETunnelProviderProtocol+Ext.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift index 56b2212a0..ccde467e9 100644 --- a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift +++ b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift @@ -142,7 +142,7 @@ extension NETunnelProviderProtocol { } // If V2Ray is enabled - if (true) { + if (false) { endpoint = Peer.endpoint(host: Config.v2rayHost, port: Config.v2rayPort) if var v2rayPorts = V2RayPorts.load() { v2rayPorts.port = v2rayPort From f142cf0bf7eb1a4d15300bf3ebabbdabc0e623c4 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Mon, 18 Sep 2023 19:52:03 +0200 Subject: [PATCH 039/106] feat: refactor V2RayPorts.swift --- IVPNClient.xcodeproj/project.pbxproj | 8 ++-- IVPNClient/Models/V2Ray/V2RayCore.swift | 20 ++++----- .../{V2RayPorts.swift => V2RaySettings.swift} | 43 ++++++++++++------- IVPNClient/Models/VPNServerList.swift | 7 +-- .../NETunnelProviderProtocol+Ext.swift | 18 +++++--- .../Extensions/UserDefaults+Ext.swift | 4 +- 6 files changed, 57 insertions(+), 43 deletions(-) rename IVPNClient/Models/V2Ray/{V2RayPorts.swift => V2RaySettings.swift} (56%) diff --git a/IVPNClient.xcodeproj/project.pbxproj b/IVPNClient.xcodeproj/project.pbxproj index e59c44894..46746b04e 100644 --- a/IVPNClient.xcodeproj/project.pbxproj +++ b/IVPNClient.xcodeproj/project.pbxproj @@ -75,7 +75,7 @@ 82351FCC241FBC8E00E6E0FD /* VPNStatusViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82351FCB241FBC8E00E6E0FD /* VPNStatusViewModelTests.swift */; }; 82351FCE2420CE6800E6E0FD /* MapMarkerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82351FCD2420CE6800E6E0FD /* MapMarkerView.swift */; }; 82351FD224222F7700E6E0FD /* ConnectionInfoPopupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82351FD124222F7700E6E0FD /* ConnectionInfoPopupView.swift */; }; - 82365E7F2AB86020006434C3 /* V2RayPorts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82365E7E2AB86020006434C3 /* V2RayPorts.swift */; }; + 82365E7F2AB86020006434C3 /* V2RaySettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82365E7E2AB86020006434C3 /* V2RaySettings.swift */; }; 823ACC292626E69F006F69AB /* GeoLookupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823ACC282626E69F006F69AB /* GeoLookupTests.swift */; }; 823ACC312626FF3E006F69AB /* IpProtocolView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823ACC302626FF3E006F69AB /* IpProtocolView.swift */; }; 823ACC3926270330006F69AB /* ConnectionInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823ACC3826270330006F69AB /* ConnectionInfoView.swift */; }; @@ -509,7 +509,7 @@ 82351FCB241FBC8E00E6E0FD /* VPNStatusViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNStatusViewModelTests.swift; sourceTree = ""; }; 82351FCD2420CE6800E6E0FD /* MapMarkerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapMarkerView.swift; sourceTree = ""; }; 82351FD124222F7700E6E0FD /* ConnectionInfoPopupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionInfoPopupView.swift; sourceTree = ""; }; - 82365E7E2AB86020006434C3 /* V2RayPorts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = V2RayPorts.swift; sourceTree = ""; }; + 82365E7E2AB86020006434C3 /* V2RaySettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = V2RaySettings.swift; sourceTree = ""; }; 823ACC282626E69F006F69AB /* GeoLookupTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeoLookupTests.swift; sourceTree = ""; }; 823ACC302626FF3E006F69AB /* IpProtocolView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IpProtocolView.swift; sourceTree = ""; }; 823ACC3826270330006F69AB /* ConnectionInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionInfoView.swift; sourceTree = ""; }; @@ -931,7 +931,7 @@ isa = PBXGroup; children = ( 8247C05F2A7CF54300A7C02F /* V2RayConfig.swift */, - 82365E7E2AB86020006434C3 /* V2RayPorts.swift */, + 82365E7E2AB86020006434C3 /* V2RaySettings.swift */, 821E35572A95DCD200AEE5C7 /* V2RayCore.swift */, 821E35592A95F77700AEE5C7 /* config.json */, ); @@ -2287,7 +2287,7 @@ 822563922431E03A00AE7F8D /* AccountView.swift in Sources */, 9CBFF02C21021D2100FE1757 /* ConnectionManager.swift in Sources */, 82D598C821A6ADF1000FABDE /* NetworkType.swift in Sources */, - 82365E7F2AB86020006434C3 /* V2RayPorts.swift in Sources */, + 82365E7F2AB86020006434C3 /* V2RaySettings.swift in Sources */, 9CC29DF81E1D59E90080F799 /* Alerts+Ext.swift in Sources */, 9CB2CE1F1DAA5258007A4D2D /* Authentication.swift in Sources */, 82DAB37B2457013900302F4C /* Service.swift in Sources */, diff --git a/IVPNClient/Models/V2Ray/V2RayCore.swift b/IVPNClient/Models/V2Ray/V2RayCore.swift index 0f3185ac0..5c9f7de80 100644 --- a/IVPNClient/Models/V2Ray/V2RayCore.swift +++ b/IVPNClient/Models/V2Ray/V2RayCore.swift @@ -65,20 +65,18 @@ class V2RayCore { } func makeConfig() -> V2RayConfig? { - guard let v2rayPorts = V2RayPorts.load() else { + guard let settings = V2RaySettings.load() else { return nil } - let host = v2rayPorts.host - let outboundIp = host.v2ray - let outboundPort = v2rayPorts.port - let inboundIp = host.host - let inboundPort = v2rayPorts.wireguard.first?.port ?? 0 - let outboundUserId = v2rayPorts.id - let tlsSrvName = host.dnsName.replacingOccurrences(of: "ivpn.net", with: "inet-telecom.com") - let config = V2RayConfig.createQuick(outboundIp: outboundIp, outboundPort: outboundPort, inboundIp: inboundIp, inboundPort: inboundPort, outboundUserId: outboundUserId, tlsSrvName: tlsSrvName) - - return config + return V2RayConfig.createQuick( + outboundIp: settings.outboundIp, + outboundPort: settings.outboundPort, + inboundIp: settings.inboundIp, + inboundPort: settings.inboundPort, + outboundUserId: settings.id, + tlsSrvName: settings.tlsSrvName() + ) } } diff --git a/IVPNClient/Models/V2Ray/V2RayPorts.swift b/IVPNClient/Models/V2Ray/V2RaySettings.swift similarity index 56% rename from IVPNClient/Models/V2Ray/V2RayPorts.swift rename to IVPNClient/Models/V2Ray/V2RaySettings.swift index 0f68d1851..85293e720 100644 --- a/IVPNClient/Models/V2Ray/V2RayPorts.swift +++ b/IVPNClient/Models/V2Ray/V2RaySettings.swift @@ -1,5 +1,5 @@ // -// V2RayPorts.swift +// V2RaySettings.swift // IVPN iOS app // https://github.com/ivpn/ios-app // @@ -23,22 +23,39 @@ import Foundation -struct V2RayPorts: Codable { +struct V2RaySettings: Codable { - let id: String - var port: Int - var host: V2RayHost - let wireguard: [V2RayPort] + var id: String + var outboundIp: String + var outboundPort: Int + var inboundIp: String + var inboundPort: Int + var dnsName: String + var wireguard: [V2RayPort] + + init(id: String = "", outboundIp: String = "", outboundPort: Int = 0, inboundIp: String = "", inboundPort: Int = 0, dnsName: String = "", wireguard: [V2RayPort] = []) { + self.id = id + self.outboundIp = outboundIp + self.outboundPort = outboundPort + self.inboundIp = inboundIp + self.inboundPort = inboundPort + self.dnsName = dnsName + self.wireguard = wireguard + } func save() { if let encoded = try? JSONEncoder().encode(self) { - UserDefaults.shared.set(encoded, forKey: UserDefaults.Key.v2RayPorts) + UserDefaults.shared.set(encoded, forKey: UserDefaults.Key.v2raySettings) } } - static func load() -> V2RayPorts? { - if let saved = UserDefaults.shared.object(forKey: UserDefaults.Key.v2RayPorts) as? Data { - if let loaded = try? JSONDecoder().decode(V2RayPorts.self, from: saved) { + func tlsSrvName() -> String { + return dnsName.replacingOccurrences(of: "ivpn.net", with: "inet-telecom.com") + } + + static func load() -> V2RaySettings? { + if let saved = UserDefaults.shared.object(forKey: UserDefaults.Key.v2raySettings) as? Data { + if let loaded = try? JSONDecoder().decode(V2RaySettings.self, from: saved) { return loaded } } @@ -52,9 +69,3 @@ struct V2RayPort: Codable { let type: String let port: Int } - -struct V2RayHost: Codable { - let host: String - let dnsName: String - let v2ray: String -} diff --git a/IVPNClient/Models/VPNServerList.swift b/IVPNClient/Models/VPNServerList.swift index bc726ea80..3e819ef54 100644 --- a/IVPNClient/Models/VPNServerList.swift +++ b/IVPNClient/Models/VPNServerList.swift @@ -211,15 +211,16 @@ class VPNServerList { if let v2ray = portsObj["v2ray"] as? [String: Any] { if let wireguard = v2ray["wireguard"] as? [[String: Any]] { var ports = [V2RayPort]() + var inboundPort = 0 for port in wireguard { let type = port["type"] as? String ?? "" let port = port["port"] as? Int ?? 0 ports.append(V2RayPort(type: type, port: port)) + inboundPort = port } let id = v2ray["id"] as? String ?? "" - let v2rayHost = V2RayHost(host: "", dnsName: "", v2ray: "") - let v2rayPorts = V2RayPorts(id: id, port: 0, host: v2rayHost, wireguard: ports) - v2rayPorts.save() + let v2raySettings = V2RaySettings(id: id, inboundPort: inboundPort, wireguard: ports) + v2raySettings.save() } } } diff --git a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift index ccde467e9..899aa2b24 100644 --- a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift +++ b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift @@ -126,13 +126,15 @@ extension NETunnelProviderProtocol { var publicKey = host.publicKey let port = getPort(settings: settings) var endpoint = Peer.endpoint(host: host.host, port: port) - var v2rayHost = host - var v2rayPort = port + var v2rayInboundIp = host.host + var v2rayOutboundIp = host.v2ray + var v2rayOutboundPort = port + var v2rayDnsName = host.dnsName if UserDefaults.shared.isMultiHop, Application.shared.serviceStatus.isEnabled(capability: .multihop), let exitHost = getExitHost() { publicKey = exitHost.publicKey endpoint = Peer.endpoint(host: host.host, port: exitHost.multihopPort) - v2rayHost = exitHost + v2rayInboundIp = exitHost.host } if let ipv6 = host.ipv6, UserDefaults.shared.isIPv6 { @@ -144,10 +146,12 @@ extension NETunnelProviderProtocol { // If V2Ray is enabled if (false) { endpoint = Peer.endpoint(host: Config.v2rayHost, port: Config.v2rayPort) - if var v2rayPorts = V2RayPorts.load() { - v2rayPorts.port = v2rayPort - v2rayPorts.host = V2RayHost(host: v2rayHost.host, dnsName: v2rayHost.dnsName, v2ray: v2rayHost.v2ray) - v2rayPorts.save() + if var v2raySettings = V2RaySettings.load() { + v2raySettings.inboundIp = v2rayInboundIp + v2raySettings.outboundIp = v2rayOutboundIp + v2raySettings.outboundPort = v2rayOutboundPort + v2raySettings.dnsName = v2rayDnsName + v2raySettings.save() } } diff --git a/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift b/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift index eb710af2d..a25c27f0c 100644 --- a/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift +++ b/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift @@ -90,7 +90,7 @@ extension UserDefaults { static let isLoggedIn = "isLoggedIn" static let antiTrackerDns = "antiTrackerDns" static let disableLanAccess = "disableLanAccess" - static let v2RayPorts = "v2RayPorts" + static let v2raySettings = "v2raySettings" } @objc dynamic var wireguardTunnelProviderError: String { @@ -277,7 +277,7 @@ extension UserDefaults { shared.removeObject(forKey: Key.isLoggedIn) shared.removeObject(forKey: Key.antiTrackerDns) shared.removeObject(forKey: Key.disableLanAccess) - shared.removeObject(forKey: Key.v2RayPorts) + shared.removeObject(forKey: Key.v2raySettings) standard.removeObject(forKey: Key.serviceStatus) standard.removeObject(forKey: Key.selectedHost) standard.removeObject(forKey: Key.selectedExitHost) From 051e9a0b1ca195299ca86b2a5eb35433dfb557ef Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Mon, 18 Sep 2023 19:57:55 +0200 Subject: [PATCH 040/106] feat: update V2RaySettings.swift --- IVPNClient/Models/V2Ray/V2RayCore.swift | 2 +- IVPNClient/Models/V2Ray/V2RaySettings.swift | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/IVPNClient/Models/V2Ray/V2RayCore.swift b/IVPNClient/Models/V2Ray/V2RayCore.swift index 5c9f7de80..442e47c24 100644 --- a/IVPNClient/Models/V2Ray/V2RayCore.swift +++ b/IVPNClient/Models/V2Ray/V2RayCore.swift @@ -75,7 +75,7 @@ class V2RayCore { inboundIp: settings.inboundIp, inboundPort: settings.inboundPort, outboundUserId: settings.id, - tlsSrvName: settings.tlsSrvName() + tlsSrvName: settings.tlsSrvName ) } diff --git a/IVPNClient/Models/V2Ray/V2RaySettings.swift b/IVPNClient/Models/V2Ray/V2RaySettings.swift index 85293e720..d08056845 100644 --- a/IVPNClient/Models/V2Ray/V2RaySettings.swift +++ b/IVPNClient/Models/V2Ray/V2RaySettings.swift @@ -33,6 +33,14 @@ struct V2RaySettings: Codable { var dnsName: String var wireguard: [V2RayPort] + var tlsSrvName: String { + return dnsName.replacingOccurrences(of: "ivpn.net", with: "inet-telecom.com") + } + + var singleHopInboundPort: Int { + return wireguard.first?.port ?? 0 + } + init(id: String = "", outboundIp: String = "", outboundPort: Int = 0, inboundIp: String = "", inboundPort: Int = 0, dnsName: String = "", wireguard: [V2RayPort] = []) { self.id = id self.outboundIp = outboundIp @@ -49,10 +57,6 @@ struct V2RaySettings: Codable { } } - func tlsSrvName() -> String { - return dnsName.replacingOccurrences(of: "ivpn.net", with: "inet-telecom.com") - } - static func load() -> V2RaySettings? { if let saved = UserDefaults.shared.object(forKey: UserDefaults.Key.v2raySettings) as? Data { if let loaded = try? JSONDecoder().decode(V2RaySettings.self, from: saved) { From 2296d042516cc915df1b7a9a61b3ca6b6c5d3f32 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Mon, 18 Sep 2023 20:10:04 +0200 Subject: [PATCH 041/106] feat: update NETunnelProviderProtocol+Ext.swift --- .../Utilities/Extensions/NETunnelProviderProtocol+Ext.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift index 899aa2b24..853902972 100644 --- a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift +++ b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift @@ -127,9 +127,9 @@ extension NETunnelProviderProtocol { let port = getPort(settings: settings) var endpoint = Peer.endpoint(host: host.host, port: port) var v2rayInboundIp = host.host - var v2rayOutboundIp = host.v2ray - var v2rayOutboundPort = port - var v2rayDnsName = host.dnsName + let v2rayOutboundIp = host.v2ray + let v2rayOutboundPort = port + let v2rayDnsName = host.dnsName if UserDefaults.shared.isMultiHop, Application.shared.serviceStatus.isEnabled(capability: .multihop), let exitHost = getExitHost() { publicKey = exitHost.publicKey From a5ff2d103e29c0befd5a14f59b495230d66ae409 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Tue, 19 Sep 2023 12:30:27 +0200 Subject: [PATCH 042/106] feat: update NETunnelProviderProtocol+Ext.swift --- .../NETunnelProviderProtocol+Ext.swift | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift index 853902972..d78a235f3 100644 --- a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift +++ b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift @@ -126,7 +126,9 @@ extension NETunnelProviderProtocol { var publicKey = host.publicKey let port = getPort(settings: settings) var endpoint = Peer.endpoint(host: host.host, port: port) + var v2raySettings = V2RaySettings.load() var v2rayInboundIp = host.host + var v2rayInboundPort = v2raySettings?.singleHopInboundPort ?? 0 let v2rayOutboundIp = host.v2ray let v2rayOutboundPort = port let v2rayDnsName = host.dnsName @@ -135,6 +137,7 @@ extension NETunnelProviderProtocol { publicKey = exitHost.publicKey endpoint = Peer.endpoint(host: host.host, port: exitHost.multihopPort) v2rayInboundIp = exitHost.host + v2rayInboundPort = exitHost.multihopPort } if let ipv6 = host.ipv6, UserDefaults.shared.isIPv6 { @@ -146,13 +149,12 @@ extension NETunnelProviderProtocol { // If V2Ray is enabled if (false) { endpoint = Peer.endpoint(host: Config.v2rayHost, port: Config.v2rayPort) - if var v2raySettings = V2RaySettings.load() { - v2raySettings.inboundIp = v2rayInboundIp - v2raySettings.outboundIp = v2rayOutboundIp - v2raySettings.outboundPort = v2rayOutboundPort - v2raySettings.dnsName = v2rayDnsName - v2raySettings.save() - } + v2raySettings?.inboundIp = v2rayInboundIp + v2raySettings?.inboundPort = v2rayInboundPort + v2raySettings?.outboundIp = v2rayOutboundIp + v2raySettings?.outboundPort = v2rayOutboundPort + v2raySettings?.dnsName = v2rayDnsName + v2raySettings?.save() } let peer = Peer( From f2536389847075b7a0066f6c592223726dac73d8 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Wed, 20 Sep 2023 08:51:34 +0200 Subject: [PATCH 043/106] feat: update build.sh --- .gitmodules | 3 - V2RayControl/ctrl.go | 39 +++ V2RayControl/go.mod | 70 +++++ V2RayControl/go.sum | 548 ++++++++++++++++++++++++++++++++++++++ V2RayControl/main/main.go | 82 ++++++ build.sh | 22 +- vendor/v2ray | 1 - 7 files changed, 749 insertions(+), 16 deletions(-) delete mode 100644 .gitmodules create mode 100644 V2RayControl/ctrl.go create mode 100644 V2RayControl/go.mod create mode 100644 V2RayControl/go.sum create mode 100644 V2RayControl/main/main.go delete mode 160000 vendor/v2ray diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index b4bc19086..000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "vendor/v2ray"] - path = vendor/v2ray - url = https://github.com/v2fly/v2ray-core diff --git a/V2RayControl/ctrl.go b/V2RayControl/ctrl.go new file mode 100644 index 000000000..8fd902485 --- /dev/null +++ b/V2RayControl/ctrl.go @@ -0,0 +1,39 @@ +package v2rayControl + +import ( + "fmt" + + core "github.com/v2fly/v2ray-core/v5" + _ "github.com/v2fly/v2ray-core/v5/main/distro/all" // required for loading configuration loaders (we use only "JSON") +) + +type Instance struct { + server *core.Instance +} + +func Start(jsonConfig string) (*Instance, error) { + config, err := core.LoadConfig("json", []byte(jsonConfig)) + if err != nil { + return nil, err + } + + server, err := core.New(config) + if err != nil { + return nil, err + } + + err = server.Start() + if err != nil { + return nil, err + } + + return &Instance{server: server}, nil +} + +func Stop(instance *Instance) error { + if instance.server == nil { + return fmt.Errorf("server instance is nil") + } + + return instance.server.Close() +} diff --git a/V2RayControl/go.mod b/V2RayControl/go.mod new file mode 100644 index 000000000..8e05a7aca --- /dev/null +++ b/V2RayControl/go.mod @@ -0,0 +1,70 @@ +module v2rayControl + +go 1.20 + +require github.com/v2fly/v2ray-core/v5 v5.7.0 + +require ( + github.com/adrg/xdg v0.4.0 // indirect + github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1 // indirect + github.com/ajg/form v1.5.1 // indirect + github.com/andybalholm/brotli v1.0.4 // indirect + github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d // indirect + github.com/bufbuild/protocompile v0.2.1-0.20230123224550-da57cd758c2f // indirect + github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165 // indirect + github.com/ebfe/bcrypt_pbkdf v0.0.0-20140212075826-3c8d2dcb253a // indirect + github.com/gaukas/godicttls v0.0.3 // indirect + github.com/go-chi/chi/v5 v5.0.8 // indirect + github.com/go-chi/render v1.0.2 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.11.2 // indirect + github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/golang/mock v1.6.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/jhump/protoreflect v1.15.0 // indirect + github.com/klauspost/compress v1.15.15 // indirect + github.com/klauspost/cpuid v1.2.3 // indirect + github.com/klauspost/reedsolomon v1.9.3 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 // indirect + github.com/mustafaturan/bus v1.0.2 // indirect + github.com/mustafaturan/monoton v1.0.0 // indirect + github.com/onsi/ginkgo/v2 v2.2.0 // indirect + github.com/patrickmn/go-cache v2.1.0+incompatible // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pion/dtls/v2 v2.2.4 // indirect + github.com/pion/logging v0.2.2 // indirect + github.com/pion/sctp v1.7.6 // indirect + github.com/pion/transport/v2 v2.0.0 // indirect + github.com/pion/udp v0.1.4 // indirect + github.com/pires/go-proxyproto v0.6.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/quic-go/qtls-go1-19 v0.3.2 // indirect + github.com/quic-go/qtls-go1-20 v0.2.2 // indirect + github.com/quic-go/quic-go v0.33.0 // indirect + github.com/refraction-networking/utls v1.3.2 // indirect + github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect + github.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4 // indirect + github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb // indirect + github.com/v2fly/BrowserBridge v0.0.0-20210430233438-0570fc1d7d08 // indirect + github.com/v2fly/VSign v0.0.0-20201108000810-e2adc24bf848 // indirect + github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e // indirect + github.com/xiaokangwang/VLite v0.0.0-20220418190619-cff95160a432 // indirect + github.com/xtaci/smux v1.5.15 // indirect + go.starlark.net v0.0.0-20220817180228-f738f5508c12 // indirect + go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d // indirect + golang.org/x/crypto v0.13.0 // indirect + golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.15.0 // indirect + golang.org/x/sys v0.12.0 // indirect + golang.org/x/text v0.13.0 // indirect + golang.org/x/tools v0.13.0 // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect + google.golang.org/grpc v1.53.0 // indirect + google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/V2RayControl/go.sum b/V2RayControl/go.sum new file mode 100644 index 000000000..62b864ef2 --- /dev/null +++ b/V2RayControl/go.sum @@ -0,0 +1,548 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/FlowerWrong/water v0.0.0-20180301012659-01a4eaa1f6f2/go.mod h1:xrG5L7lq7T2DLnPr2frMnL906CNEoKRwLB+VYFhPq2w= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= +github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= +github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1 h1:+JkXLHME8vLJafGhOH4aoV2Iu8bR55nU6iKMVfYVLjY= +github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1/go.mod h1:nuudZmJhzWtx2212z+pkuy7B6nkBqa+xwNXZHL1j8cg= +github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d h1:zsO4lp+bjv5XvPTF58Vq+qgmZEYZttJK+CWtSZhKenI= +github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d/go.mod h1:f1iKL6ZhUWvbk7PdWVmOaak10o86cqMUYEmn1CZNGEI= +github.com/bufbuild/protocompile v0.2.1-0.20230123224550-da57cd758c2f h1:IXSA5gow10s7zIOJfPOpXDtNBWCTA0715BDAhoJBXEs= +github.com/bufbuild/protocompile v0.2.1-0.20230123224550-da57cd758c2f/go.mod h1:tleDrpPTlLUVmgnEoN6qBliKWqJaZFJXqZdFjTd+ocU= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= +github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165 h1:BS21ZUJ/B5X2UVUbczfmdWH7GapPWAhxcMsDnjJTU1E= +github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/ebfe/bcrypt_pbkdf v0.0.0-20140212075826-3c8d2dcb253a h1:YtdtTUN1iH97s+6PUjLnaiKSQj4oG1/EZ3N9bx6g4kU= +github.com/ebfe/bcrypt_pbkdf v0.0.0-20140212075826-3c8d2dcb253a/go.mod h1:/CZpbhAusDOobpcb9yubw46kdYjq0zRC0Wpg9a9zFQM= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gaukas/godicttls v0.0.3 h1:YNDIf0d9adcxOijiLrEzpfZGAkNwLRzPaG6OjU7EITk= +github.com/gaukas/godicttls v0.0.3/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0= +github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/render v1.0.2 h1:4ER/udB0+fMWB2Jlf15RV3F4A2FDuYi/9f+lFttR/Lg= +github.com/go-chi/render v1.0.2/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU= +github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang-collections/go-datastructures v0.0.0-20150211160725-59788d5eb259/go.mod h1:9Qcha0gTWLw//0VNka1Cbnjvg3pNKGFdAm7E9sBabxE= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20210420193930-a4630ec28c79/go.mod h1:Opf9rtYVq0eTyX+aRVmRO9hE8ERAozcdrBxWG9Q6mkQ= +github.com/gopherjs/websocket v0.0.0-20191103002815-9a42957e2b3a/go.mod h1:jd+zY81Fx2lC4bfw58+Rflg1srqmedQjbBUejKOjYNY= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jhump/protoreflect v1.15.0 h1:U5T5/2LF0AZQFP9T4W5GfBjBaTruomrKobiR4E+oA/Q= +github.com/jhump/protoreflect v1.15.0/go.mod h1:qww51KYjD2hoCl/ohxw5cK2LSssFczrbO1t8Ld2TENs= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= +github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= +github.com/klauspost/cpuid v1.2.3 h1:CCtW0xUnWGVINKvE/WWOYKdsPV6mawAtvQuSl8guwQs= +github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/reedsolomon v1.9.3 h1:N/VzgeMfHmLc+KHMD1UL/tNkfXAt8FnUqlgXGIduwAY= +github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lunixbochs/struc v0.0.0-20190916212049-a5c72983bc42/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg= +github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 h1:EnfXoSqDfSNJv0VBNqY/88RNnhSGYkrHaO0mmFGbVsc= +github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.51 h1:0+Xg7vObnhrz/4ZCZcZh7zPXlmU0aveS2HDBd0m0qSo= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mustafaturan/bus v1.0.2 h1:2x3ErwZ0uUPwwZ5ZZoknEQprdaxr68Yl3mY8jDye1Ws= +github.com/mustafaturan/bus v1.0.2/go.mod h1:h7gfehm8TThv4Dcaa+wDQG7r7j6p74v+7ftr0Rq9i1Q= +github.com/mustafaturan/monoton v0.3.1/go.mod h1:FOnE7NV3s3EWPXb8/7+/OSdiMBbdlkV0Lz8p1dc+vy8= +github.com/mustafaturan/monoton v1.0.0 h1:8SCej+JiNn0lyps7V+Jzc1CRAkDR4EZPWrTupQ61YCQ= +github.com/mustafaturan/monoton v1.0.0/go.mod h1:FOnE7NV3s3EWPXb8/7+/OSdiMBbdlkV0Lz8p1dc+vy8= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= +github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI= +github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pion/dtls/v2 v2.0.0-rc.7/go.mod h1:U199DvHpRBN0muE9+tVN4TMy1jvEhZIZ63lk4xkvVSk= +github.com/pion/dtls/v2 v2.2.4 h1:YSfYwDQgrxMYXLBc/m7PFY5BVtWlNm/DN4qoU2CbcWg= +github.com/pion/dtls/v2 v2.2.4/go.mod h1:WGKfxqhrddne4Kg3p11FUMJrynkOY4lb25zHNO49wuw= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/sctp v1.7.6 h1:8qZTdJtbKfAns/Hv5L0PAj8FyXcsKhMH1pKUCGisQg4= +github.com/pion/sctp v1.7.6/go.mod h1:ichkYQ5tlgCQwEwvgfdcAolqx1nHbYCxo4D7zK/K0X8= +github.com/pion/transport v0.8.10 h1:lTiobMEw2PG6BH/mgIVqTV2mBp/mPT+IJLaN8ZxgdHk= +github.com/pion/transport v0.8.10/go.mod h1:tBmha/UCjpum5hqTWhfAEs3CO4/tHSg0MYRhSzR+CZ8= +github.com/pion/transport/v2 v2.0.0 h1:bsMYyqHCbkvHwj+eNCFBuxtlKndKfyGI2vaQmM3fIE4= +github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc= +github.com/pion/udp v0.1.4 h1:OowsTmu1Od3sD6i3fQUJxJn2fEvJO6L1TidgadtbTI8= +github.com/pion/udp v0.1.4/go.mod h1:G8LDo56HsFwC24LIcnT4YIDU5qcB6NepqqjP0keL2us= +github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= +github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= +github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= +github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= +github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= +github.com/refraction-networking/utls v1.3.2 h1:o+AkWB57mkcoW36ET7uJ002CpBWHu0KPxi6vzxvPnv8= +github.com/refraction-networking/utls v1.3.2/go.mod h1:fmoaOww2bxzzEpIKOebIsnBvjQpqP7L2vcm/9KUfm/E= +github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= +github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4 h1:zOjq+1/uLzn/Xo40stbvjIY/yehG0+mfmlsiEmc0xmQ= +github.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4/go.mod h1:aI+8yClBW+1uovkHw6HM01YXnYB8vohtB9C83wzx34E= +github.com/seiflotfy/cuckoofilter v0.0.0-20200416141329-862a88987de7/go.mod h1:ET5mVvNjwaGXRgZxO9UZr7X+8eAf87AfIYNwRSp9s4Y= +github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb h1:XfLJSPIOUX+osiMraVgIrMR27uMXnRJWGm1+GL8/63U= +github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg= +github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/txthinking/runnergroup v0.0.0-20200327135940-540a793bb997/go.mod h1:CLUSJbazqETbaR+i0YAhXBICV9TrKH93pziccMhmhpM= +github.com/txthinking/socks5 v0.0.0-20200327133705-caf148ab5e9d/go.mod h1:d3n8NJ6QMRb6I/WAlp4z5ZPAoaeqDmX5NgVZA0mhe+I= +github.com/txthinking/x v0.0.0-20200330144832-5ad2416896a9/go.mod h1:WgqbSEmUYSjEV3B1qmee/PpP2NYEz4bL9/+mF1ma+s4= +github.com/v2fly/BrowserBridge v0.0.0-20210430233438-0570fc1d7d08 h1:4Yh46CVE3k/lPq6hUbEdbB1u1anRBXLewm3k+L0iOMc= +github.com/v2fly/BrowserBridge v0.0.0-20210430233438-0570fc1d7d08/go.mod h1:KAuQNm+LWQCOFqdBcUgihPzRpVXRKzGbTNhfEfRZ4wY= +github.com/v2fly/VSign v0.0.0-20201108000810-e2adc24bf848 h1:p1UzXK6VAutXFFQMnre66h7g1BjRKUnLv0HfmmRoz7w= +github.com/v2fly/VSign v0.0.0-20201108000810-e2adc24bf848/go.mod h1:p80Bv154ZtrGpXMN15slDCqc9UGmfBuUzheDFBYaW/M= +github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF8gHIiADmOVOV5LS43gt3ONnlEl3xkwI= +github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU= +github.com/v2fly/v2ray-core/v5 v5.7.0 h1:84h2KMfs195EwIdj0DLStS2GhZMa65U0malDmteo3Nw= +github.com/v2fly/v2ray-core/v5 v5.7.0/go.mod h1:iFLyTcrioq55DA7Q2BdRxvYrLx4m2pKzVukmoS33aTU= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xiaokangwang/VLite v0.0.0-20220418190619-cff95160a432 h1:I/ATawgO2RerCq9ACwL0wBB8xNXZdE3J+93MCEHReRs= +github.com/xiaokangwang/VLite v0.0.0-20220418190619-cff95160a432/go.mod h1:QN7Go2ftTVfx0aCTh9RXHV8pkpi0FtmbwQw40dy61wQ= +github.com/xtaci/smux v1.5.12/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY= +github.com/xtaci/smux v1.5.15 h1:6hMiXswcleXj5oNfcJc+DXS8Vj36XX2LaX98udog6Kc= +github.com/xtaci/smux v1.5.15/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.starlark.net v0.0.0-20220817180228-f738f5508c12 h1:xOBJXWGEDwU5xSDxH6macxO11Us0AH2fTa9rmsbbF7g= +go.starlark.net v0.0.0-20220817180228-f738f5508c12/go.mod h1:VZcBMdr3cT3PnBoWunTabuSEXwVAH+ZJ5zxfs3AdASk= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d h1:ggxwEf5eu0l8v+87VhX1czFh8zJul3hK16Gmruxn7hw= +go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d/go.mod h1:tgPU4N2u9RByaTN3NC2p9xOzyFpte4jYwsIIRF7XlSc= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= +golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/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-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 h1:KR8+MyP7/qOlV+8Af01LtjL04bu7on42eVsxT4EyBQk= +google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/V2RayControl/main/main.go b/V2RayControl/main/main.go new file mode 100644 index 000000000..5bb1e79f1 --- /dev/null +++ b/V2RayControl/main/main.go @@ -0,0 +1,82 @@ +package main + +import ( + "fmt" + "time" + "v2rayControl" +) + +func main() { + fmt.Println("v2rayControl test") + + if err := v2rayControl.Start(JsonCfgTest); err != nil { + fmt.Println(err) + return + } + + fmt.Println("Started") + time.Sleep(time.Second * 5) + + fmt.Println("Stopping...") + if err := v2rayControl.Stop(); err != nil { + fmt.Println(err) + return + } + + time.Sleep(time.Second) + fmt.Println("Done") +} + +const JsonCfgTest = ` +{ + "log": { + "loglevel": "debug" + }, + "inbounds": [ + { + "port": "53142", + "protocol": "dokodemo-door", + "settings": { + "address": "91.232.28.116", + "port": 15351, + "network": "udp" + } + } + ], + "outbounds": [ + { + "tag": "proxy", + "protocol": "vmess", + "settings": { + "vnext": [ + { + "address": "91.232.28.119", + "port": 2049, + "users": [ + { + "id": "27de860d-5601-412d-8b71-baa048a94b98", + "alterId": 0, + "security": "none" + } + ] + } + ] + }, + "streamSettings": { + "network": "quic", + "security": "tls", + "quicSettings": { + "security": "", + "key": "", + "header": { + "type": "srtp" + } + }, + "tlsSettings": { + "serverName": "ua2.gw.inet-telecom.com" + } + } + } + ] +} +` diff --git a/build.sh b/build.sh index 6ff31ac76..30f719e73 100755 --- a/build.sh +++ b/build.sh @@ -1,19 +1,17 @@ #!/bin/bash -# Exit immediately if a command exits with a non-zero status. set -e -V2RAY_VER=v4.35.0 - -echo "=> ⬇️ Clone V2Ray sources.." -git submodule update --init - -echo "=> ⬇️ Get gomobile.." -cd vendor/v2ray -git checkout ${V2RAY_VER} +echo "=> Get gomobile.." +cd V2RayControl PATH=$PATH:~/go/bin go get golang.org/x/mobile/cmd/gomobile -echo "=> 🍏 Build iOS library.." -gomobile bind -trimpath -ldflags "-s -w" --target=ios -o ../../Frameworks/V2Ray.xcframework -echo "=> ✅ iOS build completed" +echo "=> Build iOS library.." +OUT_XCFRAMEWORK=../Frameworks/V2RayControl.xcframework +gomobile bind -trimpath -ldflags "-s -w" --target=ios -o ${OUT_XCFRAMEWORK} +echo "=> iOS build completed (out: ${OUT_XCFRAMEWORK})" +echo " !!!!!!!!!!!!!!!! " +echo " NOTE! The iOS project required the 'libresolv.tbd' library to be added to the project when using ${OUT_XCFRAMEWORK}" +echo " (Project->Build Phases->Link Binary With Libraries->Add Other->/usr/lib/libresolv.tbd)" +echo " !!!!!!!!!!!!!!!! " \ No newline at end of file diff --git a/vendor/v2ray b/vendor/v2ray deleted file mode 160000 index 19d75ac0c..000000000 --- a/vendor/v2ray +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 19d75ac0c1e31bc652aeb37d76c2a7351ec114c7 From 80b1fe440e47baf44e67e860cf03c9f1e0c03328 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Wed, 20 Sep 2023 14:54:29 +0200 Subject: [PATCH 044/106] feat: update config.json --- IVPNClient/Models/V2Ray/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IVPNClient/Models/V2Ray/config.json b/IVPNClient/Models/V2Ray/config.json index 335fd70ab..5a19e7f86 100644 --- a/IVPNClient/Models/V2Ray/config.json +++ b/IVPNClient/Models/V2Ray/config.json @@ -11,7 +11,7 @@ "settings":{ "address":"", "port":0, - "network":"udp,tcp" + "network":"udp" } } ], From a61b72fcb9726b2fc2b42c312b72f1c45046d4b4 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Wed, 20 Sep 2023 17:14:48 +0200 Subject: [PATCH 045/106] feat: update V2RayCore.swift --- IVPNClient/Models/V2Ray/V2RayCore.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/IVPNClient/Models/V2Ray/V2RayCore.swift b/IVPNClient/Models/V2Ray/V2RayCore.swift index 442e47c24..35d1b9a7f 100644 --- a/IVPNClient/Models/V2Ray/V2RayCore.swift +++ b/IVPNClient/Models/V2Ray/V2RayCore.swift @@ -59,6 +59,7 @@ class V2RayCore { if stopError != nil { error = stopError as Error? } + self.instance = nil } return error From 089104148ac43940c5bb5ce81eaf029802b4e2d5 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Fri, 22 Sep 2023 09:11:24 +0200 Subject: [PATCH 046/106] feat: update ConnectionManager.swift --- IVPNClient/Managers/ConnectionManager.swift | 36 ++++++++++++++++++- IVPNClient/Models/V2Ray/V2RayCore.swift | 2 ++ .../NETunnelProviderProtocol+Ext.swift | 3 +- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/IVPNClient/Managers/ConnectionManager.swift b/IVPNClient/Managers/ConnectionManager.swift index 66a4530ca..45d6d80c4 100644 --- a/IVPNClient/Managers/ConnectionManager.swift +++ b/IVPNClient/Managers/ConnectionManager.swift @@ -100,6 +100,14 @@ class ConnectionManager { self.evaluateCloseApp() } } + DispatchQueue.delay(2.5) { + if V2RayCore.shared.isV2ray && !V2RayCore.shared.reconnectWithV2ray { + V2RayCore.shared.reconnectWithV2ray = true + self.reconnect() + } else { + V2RayCore.shared.reconnectWithV2ray = false + } + } } else { self.connected = false } @@ -247,7 +255,22 @@ class ConnectionManager { return } - self.vpnManager.connect(tunnelType: self.settings.connectionProtocol.tunnelType()) + if V2RayCore.shared.isV2ray && V2RayCore.shared.reconnectWithV2ray { + DispatchQueue.global(qos: .userInitiated).async { + let error = V2RayCore.shared.start() + if error != nil { + log(.error, message: error?.localizedDescription ?? "") + } else { + log(.info, message: "V2Ray start OK") + } + } + + DispatchQueue.delay(2) { + self.vpnManager.connect(tunnelType: self.settings.connectionProtocol.tunnelType()) + } + } else { + self.vpnManager.connect(tunnelType: self.settings.connectionProtocol.tunnelType()) + } } } @@ -263,6 +286,17 @@ class ConnectionManager { } } } + + if V2RayCore.shared.isV2ray { + DispatchQueue.global(qos: .userInitiated).async { + let error = V2RayCore.shared.close() + if error != nil { + log(.error, message: error?.localizedDescription ?? "") + } else { + log(.info, message: "V2Ray stop OK") + } + } + } } func installOnDemandRules() { diff --git a/IVPNClient/Models/V2Ray/V2RayCore.swift b/IVPNClient/Models/V2Ray/V2RayCore.swift index 35d1b9a7f..644e850dd 100644 --- a/IVPNClient/Models/V2Ray/V2RayCore.swift +++ b/IVPNClient/Models/V2Ray/V2RayCore.swift @@ -30,6 +30,8 @@ class V2RayCore { static let shared = V2RayCore() var instance: V2rayControlInstance? + var isV2ray = true + var reconnectWithV2ray = false // MARK: - Methods - diff --git a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift index d78a235f3..1202eaa15 100644 --- a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift +++ b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift @@ -146,8 +146,7 @@ extension NETunnelProviderProtocol { KeyChain.wgIpv6Host = ipv6.localIP } - // If V2Ray is enabled - if (false) { + if V2RayCore.shared.isV2ray && V2RayCore.shared.reconnectWithV2ray { endpoint = Peer.endpoint(host: Config.v2rayHost, port: Config.v2rayPort) v2raySettings?.inboundIp = v2rayInboundIp v2raySettings?.inboundPort = v2rayInboundPort From 5ffc441eaf90ada356535d9e40c6335c417bff98 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Fri, 22 Sep 2023 09:20:33 +0200 Subject: [PATCH 047/106] feat: update UserDefaults+Ext.swift --- IVPNClient/Managers/ConnectionManager.swift | 6 +++--- IVPNClient/Models/V2Ray/V2RayCore.swift | 1 - .../Extensions/NETunnelProviderProtocol+Ext.swift | 2 +- .../Utilities/Extensions/UserDefaults+Ext.swift | 12 ++++++++++++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/IVPNClient/Managers/ConnectionManager.swift b/IVPNClient/Managers/ConnectionManager.swift index 45d6d80c4..591f91b43 100644 --- a/IVPNClient/Managers/ConnectionManager.swift +++ b/IVPNClient/Managers/ConnectionManager.swift @@ -101,7 +101,7 @@ class ConnectionManager { } } DispatchQueue.delay(2.5) { - if V2RayCore.shared.isV2ray && !V2RayCore.shared.reconnectWithV2ray { + if UserDefaults.shared.isV2ray && !V2RayCore.shared.reconnectWithV2ray { V2RayCore.shared.reconnectWithV2ray = true self.reconnect() } else { @@ -255,7 +255,7 @@ class ConnectionManager { return } - if V2RayCore.shared.isV2ray && V2RayCore.shared.reconnectWithV2ray { + if UserDefaults.shared.isV2ray && V2RayCore.shared.reconnectWithV2ray { DispatchQueue.global(qos: .userInitiated).async { let error = V2RayCore.shared.start() if error != nil { @@ -287,7 +287,7 @@ class ConnectionManager { } } - if V2RayCore.shared.isV2ray { + if UserDefaults.shared.isV2ray { DispatchQueue.global(qos: .userInitiated).async { let error = V2RayCore.shared.close() if error != nil { diff --git a/IVPNClient/Models/V2Ray/V2RayCore.swift b/IVPNClient/Models/V2Ray/V2RayCore.swift index 644e850dd..41ec6959c 100644 --- a/IVPNClient/Models/V2Ray/V2RayCore.swift +++ b/IVPNClient/Models/V2Ray/V2RayCore.swift @@ -30,7 +30,6 @@ class V2RayCore { static let shared = V2RayCore() var instance: V2rayControlInstance? - var isV2ray = true var reconnectWithV2ray = false // MARK: - Methods - diff --git a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift index 1202eaa15..8973feabe 100644 --- a/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift +++ b/IVPNClient/Utilities/Extensions/NETunnelProviderProtocol+Ext.swift @@ -146,7 +146,7 @@ extension NETunnelProviderProtocol { KeyChain.wgIpv6Host = ipv6.localIP } - if V2RayCore.shared.isV2ray && V2RayCore.shared.reconnectWithV2ray { + if UserDefaults.shared.isV2ray && V2RayCore.shared.reconnectWithV2ray { endpoint = Peer.endpoint(host: Config.v2rayHost, port: Config.v2rayPort) v2raySettings?.inboundIp = v2rayInboundIp v2raySettings?.inboundPort = v2rayInboundPort diff --git a/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift b/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift index a25c27f0c..dc4c8b92b 100644 --- a/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift +++ b/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift @@ -91,6 +91,8 @@ extension UserDefaults { static let antiTrackerDns = "antiTrackerDns" static let disableLanAccess = "disableLanAccess" static let v2raySettings = "v2raySettings" + static let v2rayProtocol = "v2rayProtocol" + static let isV2ray = "isV2ray" } @objc dynamic var wireguardTunnelProviderError: String { @@ -241,6 +243,14 @@ extension UserDefaults { return bool(forKey: Key.disableLanAccess) } + @objc dynamic var v2rayProtocol: String { + return string(forKey: Key.v2rayProtocol) ?? "" + } + + @objc dynamic var isV2ray: Bool { + return bool(forKey: Key.isV2ray) + } + static func registerUserDefaults() { shared.register(defaults: [Key.networkProtectionUntrustedConnect: true]) shared.register(defaults: [Key.networkProtectionTrustedDisconnect: true]) @@ -278,6 +288,8 @@ extension UserDefaults { shared.removeObject(forKey: Key.antiTrackerDns) shared.removeObject(forKey: Key.disableLanAccess) shared.removeObject(forKey: Key.v2raySettings) + shared.removeObject(forKey: Key.v2rayProtocol) + shared.removeObject(forKey: Key.isV2ray) standard.removeObject(forKey: Key.serviceStatus) standard.removeObject(forKey: Key.selectedHost) standard.removeObject(forKey: Key.selectedExitHost) From 9f21c0b037da64d245afb2bc3ba9b493ff5a17af Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Tue, 26 Sep 2023 10:39:51 +0200 Subject: [PATCH 048/106] feat: update UserDefaults+Ext.swift --- IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift b/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift index dc4c8b92b..4e6c66a83 100644 --- a/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift +++ b/IVPNClient/Utilities/Extensions/UserDefaults+Ext.swift @@ -244,7 +244,7 @@ extension UserDefaults { } @objc dynamic var v2rayProtocol: String { - return string(forKey: Key.v2rayProtocol) ?? "" + return string(forKey: Key.v2rayProtocol) ?? "quic" } @objc dynamic var isV2ray: Bool { From 0e3a7a5607fdc7653ba91d0304ff060ad41e9b07 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Tue, 26 Sep 2023 11:06:35 +0200 Subject: [PATCH 049/106] feat: update AdvancedViewController.swift --- IVPNClient/Scenes/Base.lproj/Main.storyboard | 129 ++++++++++++++---- .../AdvancedViewController.swift | 30 ++++ 2 files changed, 132 insertions(+), 27 deletions(-) diff --git a/IVPNClient/Scenes/Base.lproj/Main.storyboard b/IVPNClient/Scenes/Base.lproj/Main.storyboard index fa3f6c7f4..b46dc051a 100644 --- a/IVPNClient/Scenes/Base.lproj/Main.storyboard +++ b/IVPNClient/Scenes/Base.lproj/Main.storyboard @@ -21,7 +21,7 @@ - + From 1b8ca7c31ef8a5d37469f3ef164d3e7ae049ff01 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Tue, 10 Oct 2023 21:28:02 +0200 Subject: [PATCH 061/106] feat: update UITableViewDelegate in AdvancedViewController --- IVPNClient/Scenes/ViewControllers/AdvancedViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IVPNClient/Scenes/ViewControllers/AdvancedViewController.swift b/IVPNClient/Scenes/ViewControllers/AdvancedViewController.swift index ce9f5ccf1..5028f3c8d 100644 --- a/IVPNClient/Scenes/ViewControllers/AdvancedViewController.swift +++ b/IVPNClient/Scenes/ViewControllers/AdvancedViewController.swift @@ -228,7 +228,7 @@ extension AdvancedViewController { var urlString = "" switch section { case 1: - urlString = "https://www.ivpn.net/" + urlString = "https://www.ivpn.net/knowledgebase/ios/v2ray/" default: urlString = "https://www.ivpn.net/knowledgebase/ios/known-issues-with-native-ios-kill-switch/" } From c6989a10c76e2fd025562fc3f68c24c5124bb181 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Tue, 10 Oct 2023 21:42:32 +0200 Subject: [PATCH 062/106] feat: update selectV2rayProtocol method in AdvancedViewController --- .../Scenes/ViewControllers/AdvancedViewController.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/IVPNClient/Scenes/ViewControllers/AdvancedViewController.swift b/IVPNClient/Scenes/ViewControllers/AdvancedViewController.swift index 5028f3c8d..90bfae2e7 100644 --- a/IVPNClient/Scenes/ViewControllers/AdvancedViewController.swift +++ b/IVPNClient/Scenes/ViewControllers/AdvancedViewController.swift @@ -73,7 +73,10 @@ class AdvancedViewController: UITableViewController { @IBAction func selectV2rayProtocol(_ sender: UISegmentedControl) { let v2rayProtocol = sender.selectedSegmentIndex == 1 ? "tcp" : "quic" UserDefaults.shared.set(v2rayProtocol, forKey: UserDefaults.Key.v2rayProtocol) - evaluateReconnect(sender: sender as UIView) + + if UserDefaults.shared.isV2ray { + evaluateReconnect(sender: sender as UIView) + } } @IBAction func toggleAskToReconnect(_ sender: UISwitch) { From 685f11d70979f9cfc686a545af9b46c575e08b56 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Tue, 10 Oct 2023 21:52:44 +0200 Subject: [PATCH 063/106] fix: update UITableViewDelegate in AdvancedViewController --- .../Scenes/ViewControllers/AdvancedViewController.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IVPNClient/Scenes/ViewControllers/AdvancedViewController.swift b/IVPNClient/Scenes/ViewControllers/AdvancedViewController.swift index 90bfae2e7..6278a97a3 100644 --- a/IVPNClient/Scenes/ViewControllers/AdvancedViewController.swift +++ b/IVPNClient/Scenes/ViewControllers/AdvancedViewController.swift @@ -210,7 +210,7 @@ class AdvancedViewController: UITableViewController { extension AdvancedViewController { override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { - if indexPath.section == 2 && indexPath.row == 0 { + if indexPath.section == 3 && indexPath.row == 0 { return 60 } @@ -218,7 +218,7 @@ extension AdvancedViewController { } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if indexPath.section == 2 && indexPath.row == 1 { + if indexPath.section == 3 && indexPath.row == 1 { tableView.deselectRow(at: indexPath, animated: true) sendLogs() } From 25094f91c45ec51cf71650c59c62116d7b8a6dec Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Wed, 11 Oct 2023 10:00:44 +0200 Subject: [PATCH 064/106] feat: update UITableViewDataSource in ProtocolViewController --- IVPNClient/Scenes/ViewControllers/ProtocolViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IVPNClient/Scenes/ViewControllers/ProtocolViewController.swift b/IVPNClient/Scenes/ViewControllers/ProtocolViewController.swift index afe3d1bf7..57349e3c8 100644 --- a/IVPNClient/Scenes/ViewControllers/ProtocolViewController.swift +++ b/IVPNClient/Scenes/ViewControllers/ProtocolViewController.swift @@ -211,7 +211,7 @@ extension ProtocolViewController { cell.setup(connectionProtocol: connectionProtocol, isSettings: indexPath.section > 0) - if !validateMultiHop(connectionProtocol: connectionProtocol) || !validateCustomDNS(connectionProtocol: connectionProtocol) || !validateAntiTracker(connectionProtocol: connectionProtocol) || !validateSecureDNS(connectionProtocol: connectionProtocol) || !validateKillSwitch(connectionProtocol: connectionProtocol) { + if !validateMultiHop(connectionProtocol: connectionProtocol) || !validateCustomDNS(connectionProtocol: connectionProtocol) || !validateAntiTracker(connectionProtocol: connectionProtocol) || !validateSecureDNS(connectionProtocol: connectionProtocol) || !validateKillSwitch(connectionProtocol: connectionProtocol) || !validateV2ray(connectionProtocol: connectionProtocol) { cell.protocolLabel.textColor = UIColor.init(named: Theme.ivpnLabel6) } else { cell.protocolLabel.textColor = UIColor.init(named: Theme.ivpnLabelPrimary) From 199a825473642706d8cde5ae32d26ddd8d3f4cc1 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Wed, 11 Oct 2023 11:21:30 +0200 Subject: [PATCH 065/106] feat: update PortViewController --- IVPNClient/Scenes/ViewControllers/PortViewController.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/IVPNClient/Scenes/ViewControllers/PortViewController.swift b/IVPNClient/Scenes/ViewControllers/PortViewController.swift index b83369412..79cb1fcd9 100644 --- a/IVPNClient/Scenes/ViewControllers/PortViewController.swift +++ b/IVPNClient/Scenes/ViewControllers/PortViewController.swift @@ -87,6 +87,10 @@ class PortViewController: UITableViewController { extension PortViewController { override func numberOfSections(in tableView: UITableView) -> Int { + if UserDefaults.shared.isV2ray { + return 1 + } + return 2 } From 9e1293ba867fb8dc9cf5ebeb5fc5a1dcc9a1e9ec Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Wed, 11 Oct 2023 14:19:24 +0200 Subject: [PATCH 066/106] feat: update ConnectionSettings.swift --- IVPNClient/Enums/ConnectionSettings.swift | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/IVPNClient/Enums/ConnectionSettings.swift b/IVPNClient/Enums/ConnectionSettings.swift index 848b4c066..053e0591b 100644 --- a/IVPNClient/Enums/ConnectionSettings.swift +++ b/IVPNClient/Enums/ConnectionSettings.swift @@ -45,7 +45,7 @@ enum ConnectionSettings { return "OpenVPN, UDP \(port)" } case .wireguard(_, let port): - return "WireGuard, UDP \(port)" + return "WireGuard, \(wireguardProtocol()) \(port)" } } @@ -61,7 +61,7 @@ enum ConnectionSettings { return "OpenVPN, UDP" } case .wireguard: - return "WireGuard, UDP" + return "WireGuard, \(wireguardProtocol())" } } @@ -104,7 +104,7 @@ enum ConnectionSettings { return "UDP \(port)" } case .wireguard(_, let port): - return "UDP \(port)" + return "\(wireguardProtocol()) \(port)" } } @@ -227,10 +227,18 @@ enum ConnectionSettings { return "UDP" } case .wireguard: - return "UDP" + return wireguardProtocol() } } + func wireguardProtocol() -> String { + if UserDefaults.shared.isV2ray && UserDefaults.shared.v2rayProtocol == "tcp" { + return "TCP" + } + + return "UDP" + } + static func == (lhs: ConnectionSettings, rhs: ConnectionSettings) -> Bool { switch (lhs, rhs) { case (.ipsec, .ipsec): From 2ca3f27421291cb8488730c2c14a7a0ca38c3e1a Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Wed, 11 Oct 2023 14:34:49 +0200 Subject: [PATCH 067/106] feat: update ConnectionSettings.swift --- IVPNClient/Enums/ConnectionSettings.swift | 26 ++++++++++++++++++- .../TableCells/ProtocolTableViewCell.swift | 2 +- .../ProtocolViewController.swift | 2 +- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/IVPNClient/Enums/ConnectionSettings.swift b/IVPNClient/Enums/ConnectionSettings.swift index 053e0591b..9779a45bc 100644 --- a/IVPNClient/Enums/ConnectionSettings.swift +++ b/IVPNClient/Enums/ConnectionSettings.swift @@ -60,7 +60,11 @@ enum ConnectionSettings { case .udp: return "OpenVPN, UDP" } - case .wireguard: + case .wireguard(_, let port): + if UserDefaults.shared.isV2ray { + return "WireGuard, \(wireguardProtocol()) \(port)" + } + return "WireGuard, \(wireguardProtocol())" } } @@ -108,6 +112,26 @@ enum ConnectionSettings { } } + func formatProtocolMultiHop() -> String { + switch self { + case .ipsec: + return "IKEv2" + case .openvpn(let proto, _): + switch proto { + case .tcp: + return "TCP" + case .udp: + return "UDP" + } + case .wireguard(_, let port): + if UserDefaults.shared.isV2ray { + return "\(wireguardProtocol()) \(port)" + } + + return "\(wireguardProtocol())" + } + } + static func tunnelTypes(protocols: [ConnectionSettings]) -> [ConnectionSettings] { var filteredProtocols = [ConnectionSettings]() diff --git a/IVPNClient/Scenes/TableCells/ProtocolTableViewCell.swift b/IVPNClient/Scenes/TableCells/ProtocolTableViewCell.swift index 39b9e1684..9d09a37c0 100644 --- a/IVPNClient/Scenes/TableCells/ProtocolTableViewCell.swift +++ b/IVPNClient/Scenes/TableCells/ProtocolTableViewCell.swift @@ -94,7 +94,7 @@ class ProtocolTableViewCell: UITableViewCell { private func setupSelectAction(title: String) { protocolLabel.text = title - protocolSettingsLabel.text = UserDefaults.shared.isMultiHop ? Application.shared.settings.connectionProtocol.protocolType() : Application.shared.settings.connectionProtocol.formatProtocol() + protocolSettingsLabel.text = UserDefaults.shared.isMultiHop ? Application.shared.settings.connectionProtocol.formatProtocolMultiHop() : Application.shared.settings.connectionProtocol.formatProtocol() accessoryType = .disclosureIndicator isUserInteractionEnabled = true selectionStyle = .default diff --git a/IVPNClient/Scenes/ViewControllers/ProtocolViewController.swift b/IVPNClient/Scenes/ViewControllers/ProtocolViewController.swift index 57349e3c8..a3fa3166a 100644 --- a/IVPNClient/Scenes/ViewControllers/ProtocolViewController.swift +++ b/IVPNClient/Scenes/ViewControllers/ProtocolViewController.swift @@ -69,7 +69,7 @@ class ProtocolViewController: UITableViewController { collection.append(ConnectionSettings.tunnelTypes(protocols: Config.supportedProtocolTypes)) if connectionProtocol.tunnelType() == .wireguard { - if UserDefaults.shared.isMultiHop { + if UserDefaults.shared.isMultiHop && !UserDefaults.shared.isV2ray { collection.append([.wireguard(.udp, 1), .wireguard(.udp, 2)]) } else { collection.append([.wireguard(.udp, 0), .wireguard(.udp, 1), .wireguard(.udp, 2)]) From d44f933eec95d28030a17f1f62e0c885e070e03f Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Wed, 11 Oct 2023 16:23:27 +0200 Subject: [PATCH 068/106] feat: update ServiceStatus.swift --- IVPNClient/Models/ServiceStatus.swift | 2 +- IVPNClient/Scenes/Signup/LoginViewController.swift | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/IVPNClient/Models/ServiceStatus.swift b/IVPNClient/Models/ServiceStatus.swift index 9da217960..6d78209cf 100644 --- a/IVPNClient/Models/ServiceStatus.swift +++ b/IVPNClient/Models/ServiceStatus.swift @@ -116,7 +116,7 @@ struct ServiceStatus: Codable { func isLegacyAccount() -> Bool { let accountId = KeyChain.username ?? "" - if accountId.hasPrefix("ivpn") && currentPlan.hasPrefix("IVPN Pro") && currentPlan != "IVPN Pro" { + if accountId.hasPrefix("ivpn") && currentPlan.contains("VPN Pro") && currentPlan != "IVPN Pro" { return true } diff --git a/IVPNClient/Scenes/Signup/LoginViewController.swift b/IVPNClient/Scenes/Signup/LoginViewController.swift index 36042b089..14a3b5eac 100644 --- a/IVPNClient/Scenes/Signup/LoginViewController.swift +++ b/IVPNClient/Scenes/Signup/LoginViewController.swift @@ -279,6 +279,9 @@ extension LoginViewController { KeyChain.username = (self.userName.text ?? "").trim() guard !Application.shared.serviceStatus.isLegacyAccount() else { + navigationController?.dismiss(animated: true, completion: { + NotificationCenter.default.post(name: Notification.Name.UpdateFloatingPanelLayout, object: nil) + }) return } From 141c06786bf35af91a58ee49f30fa8de88b17568 Mon Sep 17 00:00:00 2001 From: Juraj Hilje Date: Wed, 11 Oct 2023 16:26:10 +0200 Subject: [PATCH 069/106] feat: update AccountView.swift --- .../AccountScreen/View/AccountView.swift | 4 +-- IVPNClient/Scenes/Base.lproj/Main.storyboard | 30 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/IVPNClient/Scenes/AccountScreen/View/AccountView.swift b/IVPNClient/Scenes/AccountScreen/View/AccountView.swift index ab6da068d..9962c1b07 100644 --- a/IVPNClient/Scenes/AccountScreen/View/AccountView.swift +++ b/IVPNClient/Scenes/AccountScreen/View/AccountView.swift @@ -33,7 +33,7 @@ class AccountView: UITableView { @IBOutlet weak var subscriptionLabel: UILabel! @IBOutlet weak var activeUntilLabel: UILabel! @IBOutlet weak var logOutActionButton: UIButton! - @IBOutlet weak var addMoreTimeButton: UIButton! + @IBOutlet weak var activeUntilCell: UITableViewCell! // MARK: - Properties - @@ -47,7 +47,7 @@ class AccountView: UITableView { statusLabel.backgroundColor = viewModel.statusColor subscriptionLabel.text = viewModel.subscriptionText activeUntilLabel.text = viewModel.activeUntilText - addMoreTimeButton.isHidden = Application.shared.serviceStatus.isLegacyAccount() + activeUntilCell.isHidden = Application.shared.serviceStatus.isLegacyAccount() } func initQRCode(viewModel: AccountViewModel) { diff --git a/IVPNClient/Scenes/Base.lproj/Main.storyboard b/IVPNClient/Scenes/Base.lproj/Main.storyboard index fa3f6c7f4..37046e480 100644 --- a/IVPNClient/Scenes/Base.lproj/Main.storyboard +++ b/IVPNClient/Scenes/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -528,14 +528,14 @@ - + - + + - + @@ -2497,7 +2515,7 @@ - + @@ -2672,13 +2690,13 @@ -