Enable compilation with Swift 6 for most targets
This commit is contained in:
parent
d2949b4a0b
commit
d1cf679456
@ -13,7 +13,7 @@ import MullvadTypes
|
||||
/// the first place, or when writing to it.
|
||||
private let reopenFileLogInterval: Duration = .seconds(5)
|
||||
|
||||
class LogFileOutputStream: TextOutputStream {
|
||||
class LogFileOutputStream: TextOutputStream, @unchecked Sendable {
|
||||
private let queue = DispatchQueue(label: "LogFileOutputStreamQueue", qos: .utility)
|
||||
|
||||
private let baseFileURL: URL
|
||||
|
@ -22,7 +22,7 @@ public struct OSLogHandler: LogHandler {
|
||||
let category: String
|
||||
}
|
||||
|
||||
private static var osLogRegistry: [RegistryKey: OSLog] = [:]
|
||||
nonisolated(unsafe) private static var osLogRegistry: [RegistryKey: OSLog] = [:]
|
||||
private static let registryLock = NSLock()
|
||||
|
||||
private static func getOSLog(subsystem: String, category: String) -> OSLog {
|
||||
|
@ -9,7 +9,7 @@
|
||||
import Combine
|
||||
import MullvadSettings
|
||||
|
||||
public struct AccessMethodRepositoryStub: AccessMethodRepositoryDataSource {
|
||||
public struct AccessMethodRepositoryStub: AccessMethodRepositoryDataSource, @unchecked Sendable {
|
||||
public var directAccess: PersistentAccessMethod
|
||||
|
||||
public var accessMethodsPublisher: AnyPublisher<[PersistentAccessMethod], Never> {
|
||||
|
@ -10,7 +10,7 @@ import Foundation
|
||||
import MullvadREST
|
||||
import MullvadTypes
|
||||
|
||||
struct RESTRequestExecutorStub<Success>: RESTRequestExecutor {
|
||||
struct RESTRequestExecutorStub<Success: Sendable>: RESTRequestExecutor {
|
||||
var success: (() -> Success)?
|
||||
|
||||
func execute(completionHandler: @escaping (Result<Success, Error>) -> Void) -> Cancellable {
|
||||
|
@ -10,7 +10,7 @@ import Foundation
|
||||
import MullvadTypes
|
||||
|
||||
extension REST {
|
||||
public struct APIAvailabilityTestRequest {
|
||||
public struct APIAvailabilityTestRequest: Sendable {
|
||||
let transport: RESTTransport
|
||||
|
||||
public init(transport: RESTTransport) {
|
||||
@ -21,7 +21,7 @@ extension REST {
|
||||
///
|
||||
/// - Parameter completion: Completes with `nil` if the request was successful, and `Error` otherwise.
|
||||
/// - Returns: A cancellable token to cancel the request inflight.
|
||||
public func makeRequest(completion: @escaping (Swift.Error?) -> Void) -> Cancellable {
|
||||
public func makeRequest(completion: @escaping @Sendable (Swift.Error?) -> Void) -> Cancellable {
|
||||
do {
|
||||
let factory = RequestFactory(
|
||||
hostname: defaultAPIHostname,
|
||||
|
@ -11,7 +11,7 @@ import MullvadLogging
|
||||
import MullvadTypes
|
||||
|
||||
extension REST {
|
||||
public final class AddressCache {
|
||||
public final class AddressCache: @unchecked Sendable {
|
||||
/// Logger.
|
||||
private let logger = Logger(label: "AddressCache")
|
||||
|
||||
|
@ -10,16 +10,16 @@ import Foundation
|
||||
import MullvadTypes
|
||||
import WireGuardKitTypes
|
||||
|
||||
public protocol APIQuerying {
|
||||
public protocol APIQuerying: Sendable {
|
||||
func getAddressList(
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completionHandler: @escaping ProxyCompletionHandler<[AnyIPEndpoint]>
|
||||
completionHandler: @escaping @Sendable ProxyCompletionHandler<[AnyIPEndpoint]>
|
||||
) -> Cancellable
|
||||
|
||||
func getRelays(
|
||||
etag: String?,
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completionHandler: @escaping ProxyCompletionHandler<REST.ServerRelaysCacheResponse>
|
||||
completionHandler: @escaping @Sendable ProxyCompletionHandler<REST.ServerRelaysCacheResponse>
|
||||
) -> Cancellable
|
||||
|
||||
func createApplePayment(
|
||||
@ -30,19 +30,19 @@ public protocol APIQuerying {
|
||||
func sendProblemReport(
|
||||
_ body: REST.ProblemReportRequest,
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completionHandler: @escaping ProxyCompletionHandler<Void>
|
||||
completionHandler: @escaping @Sendable ProxyCompletionHandler<Void>
|
||||
) -> Cancellable
|
||||
|
||||
func submitVoucher(
|
||||
voucherCode: String,
|
||||
accountNumber: String,
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completionHandler: @escaping ProxyCompletionHandler<REST.SubmitVoucherResponse>
|
||||
completionHandler: @escaping @Sendable ProxyCompletionHandler<REST.SubmitVoucherResponse>
|
||||
) -> Cancellable
|
||||
}
|
||||
|
||||
extension REST {
|
||||
public final class APIProxy: Proxy<AuthProxyConfiguration>, APIQuerying {
|
||||
public final class APIProxy: Proxy<AuthProxyConfiguration>, APIQuerying, @unchecked Sendable {
|
||||
public init(configuration: AuthProxyConfiguration) {
|
||||
super.init(
|
||||
name: "APIProxy",
|
||||
@ -57,7 +57,7 @@ extension REST {
|
||||
|
||||
public func getAddressList(
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completionHandler: @escaping ProxyCompletionHandler<[AnyIPEndpoint]>
|
||||
completionHandler: @escaping @Sendable ProxyCompletionHandler<[AnyIPEndpoint]>
|
||||
) -> Cancellable {
|
||||
let requestHandler = AnyRequestHandler { endpoint in
|
||||
try self.requestFactory.createRequest(
|
||||
@ -84,7 +84,7 @@ extension REST {
|
||||
public func getRelays(
|
||||
etag: String?,
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completionHandler: @escaping ProxyCompletionHandler<ServerRelaysCacheResponse>
|
||||
completionHandler: @escaping @Sendable ProxyCompletionHandler<ServerRelaysCacheResponse>
|
||||
) -> Cancellable {
|
||||
let requestHandler = AnyRequestHandler { endpoint in
|
||||
var requestBuilder = try self.requestFactory.createRequestBuilder(
|
||||
@ -240,7 +240,7 @@ extension REST {
|
||||
voucherCode: String,
|
||||
accountNumber: String,
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completionHandler: @escaping ProxyCompletionHandler<SubmitVoucherResponse>
|
||||
completionHandler: @escaping @Sendable ProxyCompletionHandler<SubmitVoucherResponse>
|
||||
) -> Cancellable {
|
||||
let requestHandler = AnyRequestHandler(
|
||||
createURLRequest: { endpoint, authorization in
|
||||
@ -283,16 +283,16 @@ extension REST {
|
||||
|
||||
// MARK: - Response types
|
||||
|
||||
public enum ServerRelaysCacheResponse {
|
||||
public enum ServerRelaysCacheResponse: Sendable {
|
||||
case notModified
|
||||
case newContent(_ etag: String?, _ rawData: Data)
|
||||
}
|
||||
|
||||
private struct CreateApplePaymentRequest: Encodable {
|
||||
private struct CreateApplePaymentRequest: Encodable, Sendable {
|
||||
let receiptString: Data
|
||||
}
|
||||
|
||||
public enum CreateApplePaymentResponse {
|
||||
public enum CreateApplePaymentResponse: Sendable {
|
||||
case noTimeAdded(_ expiry: Date)
|
||||
case timeAdded(_ timeAdded: Int, _ newExpiry: Date)
|
||||
|
||||
@ -322,12 +322,12 @@ extension REST {
|
||||
}
|
||||
}
|
||||
|
||||
private struct CreateApplePaymentRawResponse: Decodable {
|
||||
private struct CreateApplePaymentRawResponse: Decodable, Sendable {
|
||||
let timeAdded: Int
|
||||
let newExpiry: Date
|
||||
}
|
||||
|
||||
public struct ProblemReportRequest: Encodable {
|
||||
public struct ProblemReportRequest: Encodable, Sendable {
|
||||
public let address: String
|
||||
public let message: String
|
||||
public let log: String
|
||||
@ -341,11 +341,11 @@ extension REST {
|
||||
}
|
||||
}
|
||||
|
||||
private struct SubmitVoucherRequest: Encodable {
|
||||
private struct SubmitVoucherRequest: Encodable, Sendable {
|
||||
let voucherCode: String
|
||||
}
|
||||
|
||||
public struct SubmitVoucherResponse: Decodable {
|
||||
public struct SubmitVoucherResponse: Decodable, Sendable {
|
||||
public let timeAdded: Int
|
||||
public let newExpiry: Date
|
||||
|
||||
|
@ -11,17 +11,17 @@ import MullvadLogging
|
||||
import MullvadTypes
|
||||
import Operations
|
||||
|
||||
public protocol RESTAccessTokenManagement {
|
||||
public protocol RESTAccessTokenManagement: Sendable {
|
||||
func getAccessToken(
|
||||
accountNumber: String,
|
||||
completionHandler: @escaping ProxyCompletionHandler<REST.AccessTokenData>
|
||||
completionHandler: @escaping @Sendable ProxyCompletionHandler<REST.AccessTokenData>
|
||||
) -> Cancellable
|
||||
|
||||
func invalidateAllTokens()
|
||||
}
|
||||
|
||||
extension REST {
|
||||
public final class AccessTokenManager: RESTAccessTokenManagement {
|
||||
public final class AccessTokenManager: RESTAccessTokenManagement, @unchecked Sendable {
|
||||
private let logger = Logger(label: "REST.AccessTokenManager")
|
||||
private let operationQueue = AsyncOperationQueue.makeSerial()
|
||||
private let dispatchQueue = DispatchQueue(label: "REST.AccessTokenManager.dispatchQueue")
|
||||
@ -34,7 +34,7 @@ extension REST {
|
||||
|
||||
public func getAccessToken(
|
||||
accountNumber: String,
|
||||
completionHandler: @escaping ProxyCompletionHandler<REST.AccessTokenData>
|
||||
completionHandler: @escaping @Sendable ProxyCompletionHandler<REST.AccessTokenData>
|
||||
) -> Cancellable {
|
||||
let operation =
|
||||
ResultBlockOperation<REST.AccessTokenData>(dispatchQueue: dispatchQueue) { finish -> Cancellable in
|
||||
|
@ -9,10 +9,10 @@
|
||||
import Foundation
|
||||
import MullvadTypes
|
||||
|
||||
public protocol RESTAccountHandling {
|
||||
public protocol RESTAccountHandling: Sendable {
|
||||
func createAccount(
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completion: @escaping ProxyCompletionHandler<REST.NewAccountData>
|
||||
completion: @escaping @Sendable ProxyCompletionHandler<REST.NewAccountData>
|
||||
) -> Cancellable
|
||||
|
||||
func getAccountData(accountNumber: String) -> any RESTRequestExecutor<Account>
|
||||
@ -25,7 +25,7 @@ public protocol RESTAccountHandling {
|
||||
}
|
||||
|
||||
extension REST {
|
||||
public final class AccountsProxy: Proxy<AuthProxyConfiguration>, RESTAccountHandling {
|
||||
public final class AccountsProxy: Proxy<AuthProxyConfiguration>, RESTAccountHandling, @unchecked Sendable {
|
||||
public init(configuration: AuthProxyConfiguration) {
|
||||
super.init(
|
||||
name: "AccountsProxy",
|
||||
@ -135,7 +135,7 @@ extension REST {
|
||||
}
|
||||
}
|
||||
|
||||
public struct NewAccountData: Decodable {
|
||||
public struct NewAccountData: Decodable, Sendable {
|
||||
public let id: String
|
||||
public let expiry: Date
|
||||
public let maxPorts: Int
|
||||
|
@ -10,7 +10,7 @@ import Foundation
|
||||
import MullvadTypes
|
||||
|
||||
extension REST {
|
||||
public final class AuthenticationProxy: Proxy<ProxyConfiguration> {
|
||||
public final class AuthenticationProxy: Proxy<ProxyConfiguration>, @unchecked Sendable {
|
||||
public init(configuration: ProxyConfiguration) {
|
||||
super.init(
|
||||
name: "AuthenticationProxy",
|
||||
@ -57,12 +57,12 @@ extension REST {
|
||||
}
|
||||
}
|
||||
|
||||
public struct AccessTokenData: Decodable {
|
||||
public struct AccessTokenData: Decodable, Sendable {
|
||||
let accessToken: String
|
||||
let expiry: Date
|
||||
}
|
||||
|
||||
private struct AccessTokenRequest: Encodable {
|
||||
private struct AccessTokenRequest: Encodable, Sendable {
|
||||
let accountNumber: String
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import MullvadTypes
|
||||
import Operations
|
||||
|
||||
protocol RESTAuthorizationProvider {
|
||||
func getAuthorization(completion: @escaping (Result<REST.Authorization, Swift.Error>) -> Void)
|
||||
func getAuthorization(completion: @escaping @Sendable (Result<REST.Authorization, Swift.Error>) -> Void)
|
||||
-> Cancellable
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ extension REST {
|
||||
}
|
||||
|
||||
func getAuthorization(
|
||||
completion: @escaping (Result<REST.Authorization, Swift.Error>)
|
||||
completion: @escaping @Sendable (Result<REST.Authorization, Swift.Error>)
|
||||
-> Void
|
||||
) -> Cancellable {
|
||||
accessTokenManager.getAccessToken(accountNumber: accountNumber) { result in
|
||||
|
@ -13,7 +13,7 @@ import MullvadTypes
|
||||
extension REST {
|
||||
/// The API hostname and endpoint are defined in the Info.plist of the MullvadREST framework bundle
|
||||
/// This is due to not being able to target `Bundle.main` from a Unit Test environment as it gets its own bundle that would not contain the above variables.
|
||||
private static let infoDictionary = Bundle(for: AddressCache.self).infoDictionary!
|
||||
nonisolated(unsafe) private static let infoDictionary = Bundle(for: AddressCache.self).infoDictionary!
|
||||
|
||||
/// Default API hostname.
|
||||
public static let defaultAPIHostname = infoDictionary["ApiHostName"] as! String
|
||||
|
@ -8,34 +8,34 @@
|
||||
|
||||
import Foundation
|
||||
import MullvadTypes
|
||||
import WireGuardKitTypes
|
||||
@preconcurrency import WireGuardKitTypes
|
||||
|
||||
public protocol DeviceHandling {
|
||||
public protocol DeviceHandling: Sendable {
|
||||
func getDevice(
|
||||
accountNumber: String,
|
||||
identifier: String,
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completion: @escaping ProxyCompletionHandler<Device>
|
||||
completion: @escaping @Sendable ProxyCompletionHandler<Device>
|
||||
) -> Cancellable
|
||||
|
||||
func getDevices(
|
||||
accountNumber: String,
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completion: @escaping ProxyCompletionHandler<[Device]>
|
||||
completion: @escaping @Sendable ProxyCompletionHandler<[Device]>
|
||||
) -> Cancellable
|
||||
|
||||
func createDevice(
|
||||
accountNumber: String,
|
||||
request: REST.CreateDeviceRequest,
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completion: @escaping ProxyCompletionHandler<Device>
|
||||
completion: @escaping @Sendable ProxyCompletionHandler<Device>
|
||||
) -> Cancellable
|
||||
|
||||
func deleteDevice(
|
||||
accountNumber: String,
|
||||
identifier: String,
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completion: @escaping ProxyCompletionHandler<Bool>
|
||||
completion: @escaping @Sendable ProxyCompletionHandler<Bool>
|
||||
) -> Cancellable
|
||||
|
||||
func rotateDeviceKey(
|
||||
@ -43,12 +43,12 @@ public protocol DeviceHandling {
|
||||
identifier: String,
|
||||
publicKey: PublicKey,
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completion: @escaping ProxyCompletionHandler<Device>
|
||||
completion: @escaping @Sendable ProxyCompletionHandler<Device>
|
||||
) -> Cancellable
|
||||
}
|
||||
|
||||
extension REST {
|
||||
public final class DevicesProxy: Proxy<AuthProxyConfiguration>, DeviceHandling {
|
||||
public final class DevicesProxy: Proxy<AuthProxyConfiguration>, DeviceHandling, @unchecked Sendable {
|
||||
public init(configuration: AuthProxyConfiguration) {
|
||||
super.init(
|
||||
name: "DevicesProxy",
|
||||
@ -161,7 +161,7 @@ extension REST {
|
||||
accountNumber: String,
|
||||
request: CreateDeviceRequest,
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completion: @escaping ProxyCompletionHandler<Device>
|
||||
completion: @escaping @Sendable ProxyCompletionHandler<Device>
|
||||
) -> Cancellable {
|
||||
let requestHandler = AnyRequestHandler(
|
||||
createURLRequest: { endpoint, authorization in
|
||||
@ -262,7 +262,7 @@ extension REST {
|
||||
identifier: String,
|
||||
publicKey: PublicKey,
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completion: @escaping ProxyCompletionHandler<Device>
|
||||
completion: @escaping @Sendable ProxyCompletionHandler<Device>
|
||||
) -> Cancellable {
|
||||
let requestHandler = AnyRequestHandler(
|
||||
createURLRequest: { endpoint, authorization in
|
||||
@ -310,7 +310,7 @@ extension REST {
|
||||
}
|
||||
}
|
||||
|
||||
public struct CreateDeviceRequest: Encodable {
|
||||
public struct CreateDeviceRequest: Encodable, Sendable {
|
||||
let publicKey: PublicKey
|
||||
let hijackDNS: Bool
|
||||
|
||||
@ -332,7 +332,7 @@ extension REST {
|
||||
}
|
||||
}
|
||||
|
||||
private struct RotateDeviceKeyRequest: Encodable {
|
||||
private struct RotateDeviceKeyRequest: Encodable, Sendable {
|
||||
let publicKey: PublicKey
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
|
@ -11,7 +11,7 @@ import MullvadTypes
|
||||
|
||||
extension REST {
|
||||
/// An error type returned by REST API classes.
|
||||
public enum Error: LocalizedError, WrappingError {
|
||||
public enum Error: LocalizedError, WrappingError, Sendable {
|
||||
/// Failure to create URL request.
|
||||
case createURLRequest(Swift.Error)
|
||||
|
||||
@ -80,7 +80,7 @@ extension REST {
|
||||
}
|
||||
}
|
||||
|
||||
public struct ServerErrorResponse: Decodable {
|
||||
public struct ServerErrorResponse: Decodable, Sendable {
|
||||
public let code: ServerResponseCode
|
||||
public let detail: String?
|
||||
|
||||
@ -103,7 +103,7 @@ extension REST {
|
||||
}
|
||||
}
|
||||
|
||||
public struct ServerResponseCode: RawRepresentable, Equatable {
|
||||
public struct ServerResponseCode: RawRepresentable, Equatable, Sendable {
|
||||
public static let invalidAccount = ServerResponseCode(rawValue: "INVALID_ACCOUNT")
|
||||
public static let keyLimitReached = ServerResponseCode(rawValue: "KEY_LIMIT_REACHED")
|
||||
public static let publicKeyNotFound = ServerResponseCode(rawValue: "PUBKEY_NOT_FOUND")
|
||||
|
@ -12,7 +12,7 @@ import MullvadTypes
|
||||
import Operations
|
||||
|
||||
extension REST {
|
||||
class NetworkOperation<Success>: ResultOperation<Success> {
|
||||
class NetworkOperation<Success: Sendable>: ResultOperation<Success>, @unchecked Sendable {
|
||||
private let requestHandler: RESTRequestHandler
|
||||
private let responseHandler: any RESTResponseHandler<Success>
|
||||
|
||||
|
@ -10,10 +10,10 @@ import Foundation
|
||||
import MullvadTypes
|
||||
import Operations
|
||||
|
||||
public typealias ProxyCompletionHandler<Success> = (Result<Success, Swift.Error>) -> Void
|
||||
public typealias ProxyCompletionHandler<Success: Sendable> = @Sendable (Result<Success, Swift.Error>) -> Void
|
||||
|
||||
extension REST {
|
||||
public class Proxy<ConfigurationType: ProxyConfiguration> {
|
||||
public class Proxy<ConfigurationType: ProxyConfiguration>: @unchecked Sendable {
|
||||
/// Synchronization queue used by network operations.
|
||||
let dispatchQueue: DispatchQueue
|
||||
|
||||
@ -43,7 +43,7 @@ extension REST {
|
||||
self.responseDecoder = responseDecoder
|
||||
}
|
||||
|
||||
func makeRequestExecutor<Success>(
|
||||
func makeRequestExecutor<Success: Sendable>(
|
||||
name: String,
|
||||
requestHandler: RESTRequestHandler,
|
||||
responseHandler: some RESTResponseHandler<Success>
|
||||
@ -61,7 +61,7 @@ extension REST {
|
||||
}
|
||||
|
||||
/// Factory object producing instances of `NetworkOperation`.
|
||||
private struct NetworkOperationFactory<Success, ConfigurationType: ProxyConfiguration> {
|
||||
private struct NetworkOperationFactory<Success: Sendable, ConfigurationType: ProxyConfiguration> {
|
||||
let dispatchQueue: DispatchQueue
|
||||
let configuration: ConfigurationType
|
||||
|
||||
@ -87,7 +87,7 @@ extension REST {
|
||||
}
|
||||
|
||||
/// Network request executor that supports block-based and async execution flows.
|
||||
private struct RequestExecutor<Success, ConfigurationType: ProxyConfiguration>: RESTRequestExecutor {
|
||||
private struct RequestExecutor<Success: Sendable, ConfigurationType: ProxyConfiguration>: RESTRequestExecutor {
|
||||
let operationFactory: NetworkOperationFactory<Success, ConfigurationType>
|
||||
let operationQueue: AsyncOperationQueue
|
||||
|
||||
@ -120,7 +120,7 @@ extension REST {
|
||||
}
|
||||
}
|
||||
|
||||
func execute(completionHandler: @escaping ProxyCompletionHandler<Success>) -> Cancellable {
|
||||
func execute(completionHandler: @escaping @Sendable ProxyCompletionHandler<Success>) -> Cancellable {
|
||||
return execute(retryStrategy: .noRetry, completionHandler: completionHandler)
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ extension REST {
|
||||
}
|
||||
}
|
||||
|
||||
public class ProxyConfiguration {
|
||||
public class ProxyConfiguration: @unchecked Sendable {
|
||||
public let transportProvider: RESTTransportProvider
|
||||
public let addressCacheStore: AddressCache
|
||||
|
||||
@ -142,7 +142,7 @@ extension REST {
|
||||
}
|
||||
}
|
||||
|
||||
public class AuthProxyConfiguration: ProxyConfiguration {
|
||||
public class AuthProxyConfiguration: ProxyConfiguration, @unchecked Sendable {
|
||||
public let accessTokenManager: RESTAccessTokenManagement
|
||||
|
||||
public init(
|
||||
|
@ -10,15 +10,15 @@ import Foundation
|
||||
import protocol MullvadTypes.Cancellable
|
||||
|
||||
public protocol RESTRequestExecutor<Success> {
|
||||
associatedtype Success
|
||||
associatedtype Success: Sendable
|
||||
|
||||
/// Execute new network request with `.noRetry` strategy and receive the result in a completion handler on main queue.
|
||||
func execute(completionHandler: @escaping (Result<Success, Swift.Error>) -> Void) -> Cancellable
|
||||
func execute(completionHandler: @escaping @Sendable (Result<Success, Swift.Error>) -> Void) -> Cancellable
|
||||
|
||||
/// Execute new network request and receive the result in a completion handler on main queue.
|
||||
func execute(
|
||||
retryStrategy: REST.RetryStrategy,
|
||||
completionHandler: @escaping (Result<Success, Swift.Error>) -> Void
|
||||
completionHandler: @escaping @Sendable (Result<Success, Swift.Error>) -> Void
|
||||
) -> Cancellable
|
||||
|
||||
/// Execute new network request with `.noRetry` strategy and receive the result back via async flow.
|
||||
|
@ -29,7 +29,7 @@ extension REST {
|
||||
|
||||
let authorizationProvider: RESTAuthorizationProvider?
|
||||
|
||||
init(createURLRequest: @escaping (AnyIPEndpoint) throws -> REST.Request) {
|
||||
init(createURLRequest: @escaping @Sendable (AnyIPEndpoint) throws -> REST.Request) {
|
||||
_createURLRequest = { endpoint, _ in
|
||||
try createURLRequest(endpoint)
|
||||
}
|
||||
@ -37,7 +37,7 @@ extension REST {
|
||||
}
|
||||
|
||||
init(
|
||||
createURLRequest: @escaping (AnyIPEndpoint, REST.Authorization) throws -> REST.Request,
|
||||
createURLRequest: @escaping @Sendable (AnyIPEndpoint, REST.Authorization) throws -> REST.Request,
|
||||
authorizationProvider: RESTAuthorizationProvider
|
||||
) {
|
||||
_createURLRequest = { endpoint, authorization in
|
||||
|
@ -10,7 +10,7 @@ import Foundation
|
||||
|
||||
extension REST {
|
||||
private static let nslock = NSLock()
|
||||
private static var taskCount: UInt32 = 0
|
||||
nonisolated(unsafe) private static var taskCount: UInt32 = 0
|
||||
|
||||
static func getTaskIdentifier(name: String) -> String {
|
||||
nslock.lock()
|
||||
|
@ -11,7 +11,7 @@ import MullvadLogging
|
||||
import Network
|
||||
import Security
|
||||
|
||||
final class SSLPinningURLSessionDelegate: NSObject, URLSessionDelegate {
|
||||
final class SSLPinningURLSessionDelegate: NSObject, URLSessionDelegate, @unchecked Sendable {
|
||||
private let sslHostname: String
|
||||
private let trustedRootCertificates: [SecCertificate]
|
||||
private let addressCache: REST.AddressCache
|
||||
@ -29,7 +29,7 @@ final class SSLPinningURLSessionDelegate: NSObject, URLSessionDelegate {
|
||||
func urlSession(
|
||||
_ session: URLSession,
|
||||
didReceive challenge: URLAuthenticationChallenge,
|
||||
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
|
||||
completionHandler: @escaping @Sendable (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
|
||||
) {
|
||||
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust,
|
||||
let serverTrust = challenge.protectionSpace.serverTrust {
|
||||
|
@ -11,7 +11,7 @@ import MullvadTypes
|
||||
import Network
|
||||
|
||||
extension REST {
|
||||
public struct ServerLocation: Codable, Equatable {
|
||||
public struct ServerLocation: Codable, Equatable, Sendable {
|
||||
public let country: String
|
||||
public let city: String
|
||||
public let latitude: Double
|
||||
@ -25,7 +25,7 @@ extension REST {
|
||||
}
|
||||
}
|
||||
|
||||
public struct BridgeRelay: Codable, Equatable {
|
||||
public struct BridgeRelay: Codable, Equatable, Sendable {
|
||||
public let hostname: String
|
||||
public let active: Bool
|
||||
public let owned: Bool
|
||||
@ -50,7 +50,7 @@ extension REST {
|
||||
}
|
||||
}
|
||||
|
||||
public struct ServerRelay: Codable, Equatable {
|
||||
public struct ServerRelay: Codable, Equatable, Sendable {
|
||||
public let hostname: String
|
||||
public let active: Bool
|
||||
public let owned: Bool
|
||||
@ -99,7 +99,7 @@ extension REST {
|
||||
}
|
||||
}
|
||||
|
||||
public struct ServerWireguardTunnels: Codable, Equatable {
|
||||
public struct ServerWireguardTunnels: Codable, Equatable, Sendable {
|
||||
public let ipv4Gateway: IPv4Address
|
||||
public let ipv6Gateway: IPv6Address
|
||||
public let portRanges: [[UInt16]]
|
||||
@ -121,19 +121,19 @@ extension REST {
|
||||
}
|
||||
}
|
||||
|
||||
public struct ServerShadowsocks: Codable, Equatable {
|
||||
public struct ServerShadowsocks: Codable, Equatable, Sendable {
|
||||
public let `protocol`: String
|
||||
public let port: UInt16
|
||||
public let cipher: String
|
||||
public let password: String
|
||||
}
|
||||
|
||||
public struct ServerBridges: Codable, Equatable {
|
||||
public struct ServerBridges: Codable, Equatable, Sendable {
|
||||
public let shadowsocks: [ServerShadowsocks]
|
||||
public let relays: [BridgeRelay]
|
||||
}
|
||||
|
||||
public struct ServerRelaysResponse: Codable, Equatable {
|
||||
public struct ServerRelaysResponse: Codable, Equatable, Sendable {
|
||||
public let locations: [String: ServerLocation]
|
||||
public let wireguard: ServerWireguardTunnels
|
||||
public let bridge: ServerBridges
|
||||
|
@ -9,7 +9,7 @@
|
||||
import MullvadSettings
|
||||
import MullvadTypes
|
||||
|
||||
public class IPOverrideWrapper: RelayCacheProtocol {
|
||||
public final class IPOverrideWrapper: RelayCacheProtocol {
|
||||
private let relayCache: RelayCacheProtocol
|
||||
private let ipOverrideRepository: any IPOverrideRepositoryProtocol
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum NoRelaysSatisfyingConstraintsReason {
|
||||
public enum NoRelaysSatisfyingConstraintsReason: Sendable {
|
||||
case filterConstraintNotMatching
|
||||
case invalidPort
|
||||
case entryEqualsExit
|
||||
@ -19,7 +19,7 @@ public enum NoRelaysSatisfyingConstraintsReason {
|
||||
case relayConstraintNotMatching
|
||||
}
|
||||
|
||||
public struct NoRelaysSatisfyingConstraintsError: LocalizedError {
|
||||
public struct NoRelaysSatisfyingConstraintsError: LocalizedError, Sendable {
|
||||
public let reason: NoRelaysSatisfyingConstraintsReason
|
||||
|
||||
public var errorDescription: String? {
|
||||
|
@ -9,7 +9,7 @@
|
||||
import Foundation
|
||||
import MullvadTypes
|
||||
|
||||
public protocol RelayCacheProtocol {
|
||||
public protocol RelayCacheProtocol: Sendable {
|
||||
/// Reads from a cached list,
|
||||
/// which falls back to reading from prebundled relays if there was no cache hit
|
||||
func read() throws -> StoredRelays
|
||||
@ -23,9 +23,9 @@ public protocol RelayCacheProtocol {
|
||||
|
||||
/// - Warning: `RelayCache` should not be used directly. It should be used through `IPOverrideWrapper` to have
|
||||
/// ip overrides applied.
|
||||
public final class RelayCache: RelayCacheProtocol {
|
||||
public final class RelayCache: RelayCacheProtocol, Sendable {
|
||||
private let fileURL: URL
|
||||
private let fileCache: any FileCacheProtocol<StoredRelays>
|
||||
nonisolated(unsafe) private let fileCache: any FileCacheProtocol<StoredRelays>
|
||||
|
||||
/// Designated initializer
|
||||
public init(cacheDirectory: URL) {
|
||||
|
@ -19,7 +19,7 @@ public protocol RelaySelectorProtocol {
|
||||
}
|
||||
|
||||
/// Struct describing the selected relay.
|
||||
public struct SelectedRelay: Equatable, Codable {
|
||||
public struct SelectedRelay: Equatable, Codable, Sendable {
|
||||
/// Selected relay endpoint.
|
||||
public let endpoint: MullvadEndpoint
|
||||
|
||||
@ -43,7 +43,7 @@ extension SelectedRelay: CustomDebugStringConvertible {
|
||||
}
|
||||
}
|
||||
|
||||
public struct SelectedRelays: Equatable, Codable {
|
||||
public struct SelectedRelays: Equatable, Codable, Sendable {
|
||||
public let entry: SelectedRelay?
|
||||
public let exit: SelectedRelay
|
||||
public let retryAttempt: UInt
|
||||
|
@ -9,7 +9,7 @@
|
||||
import MullvadSettings
|
||||
import MullvadTypes
|
||||
|
||||
public final class RelaySelectorWrapper: RelaySelectorProtocol {
|
||||
public final class RelaySelectorWrapper: RelaySelectorProtocol, Sendable {
|
||||
let relayCache: RelayCacheProtocol
|
||||
|
||||
public init(relayCache: RelayCacheProtocol) {
|
||||
|
@ -34,7 +34,7 @@ struct Transformer<Inner: IteratorProtocol>: IteratorProtocol {
|
||||
private var inner: Inner
|
||||
private let transformer: (Inner.Element?) -> Inner.Element?
|
||||
|
||||
init(inner: Inner, transform: @escaping (Inner.Element?) -> Inner.Element?) {
|
||||
init(inner: Inner, transform: @escaping @Sendable (Inner.Element?) -> Inner.Element?) {
|
||||
self.inner = inner
|
||||
self.transformer = transform
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import Foundation
|
||||
import MullvadTypes
|
||||
|
||||
extension REST {
|
||||
public struct RetryStrategy {
|
||||
public struct RetryStrategy: Sendable {
|
||||
public var maxRetryCount: Int
|
||||
public var delay: RetryDelay
|
||||
public var applyJitter: Bool
|
||||
@ -42,34 +42,34 @@ extension REST {
|
||||
}
|
||||
|
||||
/// Strategy configured to never retry.
|
||||
public static var noRetry = RetryStrategy(
|
||||
public static let noRetry = RetryStrategy(
|
||||
maxRetryCount: 0,
|
||||
delay: .never,
|
||||
applyJitter: false
|
||||
)
|
||||
|
||||
/// Strategy configured with 2 retry attempts and exponential backoff.
|
||||
public static var `default` = RetryStrategy(
|
||||
public static let `default` = RetryStrategy(
|
||||
maxRetryCount: 2,
|
||||
delay: defaultRetryDelay,
|
||||
applyJitter: true
|
||||
)
|
||||
|
||||
/// Strategy configured with 10 retry attempts and exponential backoff.
|
||||
public static var aggressive = RetryStrategy(
|
||||
public static let aggressive = RetryStrategy(
|
||||
maxRetryCount: 10,
|
||||
delay: defaultRetryDelay,
|
||||
applyJitter: true
|
||||
)
|
||||
|
||||
/// Default retry delay.
|
||||
public static var defaultRetryDelay: RetryDelay = .exponentialBackoff(
|
||||
public static let defaultRetryDelay: RetryDelay = .exponentialBackoff(
|
||||
initial: .seconds(2),
|
||||
multiplier: 2,
|
||||
maxDelay: .seconds(8)
|
||||
)
|
||||
|
||||
public static var postQuantumKeyExchange = RetryStrategy(
|
||||
public static let postQuantumKeyExchange = RetryStrategy(
|
||||
maxRetryCount: 10,
|
||||
delay: .exponentialBackoff(
|
||||
initial: .seconds(10),
|
||||
@ -79,7 +79,7 @@ extension REST {
|
||||
applyJitter: true
|
||||
)
|
||||
|
||||
public static var failedMigrationRecovery = RetryStrategy(
|
||||
public static let failedMigrationRecovery = RetryStrategy(
|
||||
maxRetryCount: .max,
|
||||
delay: .exponentialBackoff(
|
||||
initial: .seconds(5),
|
||||
@ -90,7 +90,7 @@ extension REST {
|
||||
)
|
||||
}
|
||||
|
||||
public enum RetryDelay: Equatable {
|
||||
public enum RetryDelay: Equatable, Sendable {
|
||||
/// Never wait to retry.
|
||||
case never
|
||||
|
||||
|
@ -10,7 +10,7 @@ import Combine
|
||||
import Foundation
|
||||
import MullvadSettings
|
||||
|
||||
class AccessMethodIterator {
|
||||
final class AccessMethodIterator: @unchecked Sendable {
|
||||
private let dataSource: AccessMethodRepositoryDataSource
|
||||
|
||||
private var index = 0
|
||||
|
@ -24,7 +24,7 @@ public final class URLSessionTransport: RESTTransport {
|
||||
|
||||
public func sendRequest(
|
||||
_ request: URLRequest,
|
||||
completion: @escaping (Data?, URLResponse?, Swift.Error?) -> Void
|
||||
completion: @escaping @Sendable (Data?, URLResponse?, Swift.Error?) -> Void
|
||||
) -> Cancellable {
|
||||
let dataTask = urlSession.dataTask(with: request, completionHandler: completion)
|
||||
dataTask.resume()
|
||||
|
@ -9,7 +9,7 @@ import Foundation
|
||||
import MullvadRustRuntime
|
||||
import MullvadTypes
|
||||
|
||||
public final class EncryptedDNSTransport: RESTTransport {
|
||||
public final class EncryptedDNSTransport: RESTTransport, @unchecked Sendable {
|
||||
public var name: String {
|
||||
"encrypted-dns-url-session"
|
||||
}
|
||||
@ -39,7 +39,7 @@ public final class EncryptedDNSTransport: RESTTransport {
|
||||
/// most of the time starting the DNS proxy was already spent.
|
||||
public func sendRequest(
|
||||
_ request: URLRequest,
|
||||
completion: @escaping (Data?, URLResponse?, (any Error)?) -> Void
|
||||
completion: @escaping @Sendable (Data?, URLResponse?, (any Error)?) -> Void
|
||||
) -> any Cancellable {
|
||||
dispatchQueue.async { [weak self] in
|
||||
guard let self else { return }
|
||||
@ -58,7 +58,7 @@ public final class EncryptedDNSTransport: RESTTransport {
|
||||
return components?.url
|
||||
}
|
||||
|
||||
let wrappedCompletionHandler: (Data?, URLResponse?, (any Error)?)
|
||||
let wrappedCompletionHandler: @Sendable (Data?, URLResponse?, (any Error)?)
|
||||
-> Void = { [weak self] data, response, maybeError in
|
||||
if maybeError != nil {
|
||||
self?.encryptedDnsProxy.stop()
|
||||
@ -77,7 +77,7 @@ public final class EncryptedDNSTransport: RESTTransport {
|
||||
}
|
||||
|
||||
return AnyCancellable { [weak self] in
|
||||
self?.dispatchQueue.async {
|
||||
self?.dispatchQueue.async { [weak self] in
|
||||
self?.dnsProxyTask?.cancel()
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,9 @@
|
||||
import Foundation
|
||||
import MullvadTypes
|
||||
|
||||
public protocol RESTTransport {
|
||||
public protocol RESTTransport: Sendable {
|
||||
var name: String { get }
|
||||
|
||||
func sendRequest(_ request: URLRequest, completion: @escaping (Data?, URLResponse?, Error?) -> Void) -> Cancellable
|
||||
func sendRequest(_ request: URLRequest, completion: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void)
|
||||
-> Cancellable
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ extension REST {
|
||||
public struct AnyTransportProvider: RESTTransportProvider {
|
||||
private let block: () -> RESTTransport?
|
||||
|
||||
public init(_ block: @escaping () -> RESTTransport?) {
|
||||
public init(_ block: @escaping @Sendable () -> RESTTransport?) {
|
||||
self.block = block
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import Foundation
|
||||
import MullvadTypes
|
||||
import Network
|
||||
|
||||
public struct ShadowsocksConfiguration: Codable, Equatable {
|
||||
public struct ShadowsocksConfiguration: Codable, Equatable, Sendable {
|
||||
public let address: AnyIPAddress
|
||||
public let port: UInt16
|
||||
public let password: String
|
||||
|
@ -9,14 +9,14 @@
|
||||
import Foundation
|
||||
import MullvadTypes
|
||||
|
||||
public protocol ShadowsocksConfigurationCacheProtocol {
|
||||
public protocol ShadowsocksConfigurationCacheProtocol: Sendable {
|
||||
func read() throws -> ShadowsocksConfiguration
|
||||
func write(_ configuration: ShadowsocksConfiguration) throws
|
||||
func clear() throws
|
||||
}
|
||||
|
||||
/// Holds a shadowsocks configuration object backed by a caching mechanism shared across processes
|
||||
public final class ShadowsocksConfigurationCache: ShadowsocksConfigurationCacheProtocol {
|
||||
public final class ShadowsocksConfigurationCache: ShadowsocksConfigurationCacheProtocol, @unchecked Sendable {
|
||||
private let configurationLock = NSLock()
|
||||
private var cachedConfiguration: ShadowsocksConfiguration?
|
||||
private let fileCache: FileCache<ShadowsocksConfiguration>
|
||||
|
@ -10,18 +10,18 @@ import Foundation
|
||||
import MullvadSettings
|
||||
import MullvadTypes
|
||||
|
||||
public protocol ShadowsocksLoaderProtocol {
|
||||
public protocol ShadowsocksLoaderProtocol: Sendable {
|
||||
func load() throws -> ShadowsocksConfiguration
|
||||
func clear() throws
|
||||
}
|
||||
|
||||
public class ShadowsocksLoader: ShadowsocksLoaderProtocol {
|
||||
public final class ShadowsocksLoader: ShadowsocksLoaderProtocol, Sendable {
|
||||
let cache: ShadowsocksConfigurationCacheProtocol
|
||||
let relaySelector: ShadowsocksRelaySelectorProtocol
|
||||
let settingsUpdater: SettingsUpdater
|
||||
|
||||
private var observer: SettingsObserverBlock!
|
||||
private var tunnelSettings = LatestTunnelSettings()
|
||||
nonisolated(unsafe) private var observer: SettingsObserverBlock!
|
||||
nonisolated(unsafe) private var tunnelSettings = LatestTunnelSettings()
|
||||
private let settingsStrategy = TunnelSettingsStrategy()
|
||||
|
||||
deinit {
|
||||
|
@ -10,7 +10,7 @@ import Foundation
|
||||
import MullvadSettings
|
||||
import MullvadTypes
|
||||
|
||||
public protocol ShadowsocksRelaySelectorProtocol {
|
||||
public protocol ShadowsocksRelaySelectorProtocol: Sendable {
|
||||
func selectRelay(with settings: LatestTunnelSettings) throws -> REST.BridgeRelay?
|
||||
|
||||
func getBridges() throws -> REST.ServerShadowsocks?
|
||||
|
@ -44,7 +44,7 @@ public final class ShadowsocksTransport: RESTTransport {
|
||||
|
||||
public func sendRequest(
|
||||
_ request: URLRequest,
|
||||
completion: @escaping (Data?, URLResponse?, Swift.Error?) -> Void
|
||||
completion: @escaping @Sendable (Data?, URLResponse?, Swift.Error?) -> Void
|
||||
) -> Cancellable {
|
||||
// Start the Shadowsocks proxy in order to get a local port
|
||||
shadowsocksProxy.start()
|
||||
|
@ -16,7 +16,7 @@ extension NWConnection {
|
||||
- exactLength: exact number of bytes to read.
|
||||
- completion: a completion handler.
|
||||
*/
|
||||
func receive(exactLength: Int, completion: @escaping (Data?, ContentContext?, Bool, NWError?) -> Void) {
|
||||
func receive(exactLength: Int, completion: @Sendable @escaping (Data?, ContentContext?, Bool, NWError?) -> Void) {
|
||||
receive(minimumIncompleteLength: exactLength, maximumLength: exactLength, completion: completion)
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
import Foundation
|
||||
|
||||
/// Address type supported by socks protocol
|
||||
enum Socks5AddressType: UInt8 {
|
||||
enum Socks5AddressType: UInt8, Sendable {
|
||||
case ipv4 = 0x01
|
||||
case domainName = 0x03
|
||||
case ipv6 = 0x04
|
||||
|
@ -14,13 +14,13 @@ enum Socks5AuthenticationMethod: UInt8 {
|
||||
case usernamePassword = 0x02
|
||||
}
|
||||
|
||||
struct Socks5Authentication {
|
||||
struct Socks5Authentication: Sendable {
|
||||
let connection: NWConnection
|
||||
let endpoint: Socks5Endpoint
|
||||
let configuration: Socks5Configuration
|
||||
|
||||
typealias AuthenticationComplete = () -> Void
|
||||
typealias AuthenticationFailure = (Error) -> Void
|
||||
typealias AuthenticationComplete = @Sendable () -> Void
|
||||
typealias AuthenticationFailure = @Sendable (Error) -> Void
|
||||
|
||||
func authenticate(onComplete: @escaping AuthenticationComplete, onFailure: @escaping AuthenticationFailure) {
|
||||
guard let username = configuration.username, let password = configuration.password else {
|
||||
|
@ -11,7 +11,7 @@ import MullvadTypes
|
||||
|
||||
/// Socks5 configuration.
|
||||
/// - See: ``URLSessionSocks5Transport``
|
||||
public struct Socks5Configuration: Equatable {
|
||||
public struct Socks5Configuration: Equatable, Sendable {
|
||||
/// The socks proxy endpoint.
|
||||
public var proxyEndpoint: AnyIPEndpoint
|
||||
|
||||
|
@ -17,10 +17,10 @@ struct Socks5ConnectNegotiation {
|
||||
let endpoint: Socks5Endpoint
|
||||
|
||||
/// Completion handler invoked on success.
|
||||
let onComplete: (Socks5ConnectReply) -> Void
|
||||
let onComplete: @Sendable (Socks5ConnectReply) -> Void
|
||||
|
||||
/// Failure handler invoked on error.
|
||||
let onFailure: (Error) -> Void
|
||||
let onFailure: @Sendable (Error) -> Void
|
||||
|
||||
/// Initiate negotiation by sending a connect command to the socks proxy.
|
||||
func perform() {
|
||||
|
@ -9,7 +9,7 @@ import Foundation
|
||||
import Network
|
||||
|
||||
/// A bidirectional data connection between a local endpoint and remote endpoint over socks proxy.
|
||||
final class Socks5Connection {
|
||||
final class Socks5Connection: Sendable {
|
||||
/// The remote endpoint to which the client wants to establish connection over the socks proxy.
|
||||
let remoteServerEndpoint: Socks5Endpoint
|
||||
let configuration: Socks5Configuration
|
||||
@ -75,7 +75,7 @@ final class Socks5Connection {
|
||||
|
||||
- Parameter newStateHandler: state handler block.
|
||||
*/
|
||||
func setStateHandler(_ newStateHandler: ((Socks5Connection, State) -> Void)?) {
|
||||
func setStateHandler(_ newStateHandler: (@Sendable (Socks5Connection, State) -> Void)?) {
|
||||
queue.async { [self] in
|
||||
stateHandler = newStateHandler
|
||||
}
|
||||
@ -110,8 +110,8 @@ final class Socks5Connection {
|
||||
private let queue: DispatchQueue
|
||||
private let localConnection: NWConnection
|
||||
private let remoteConnection: NWConnection
|
||||
private var stateHandler: ((Socks5Connection, State) -> Void)?
|
||||
private var state: State = .initialized {
|
||||
nonisolated(unsafe) private var stateHandler: (@Sendable (Socks5Connection, State) -> Void)?
|
||||
nonisolated(unsafe) private var state: State = .initialized {
|
||||
didSet {
|
||||
stateHandler?(self, state)
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import Foundation
|
||||
import Network
|
||||
|
||||
/// The object handling bidirectional streaming of data between local and remote connection.
|
||||
struct Socks5DataStreamHandler {
|
||||
struct Socks5DataStreamHandler: Sendable {
|
||||
/// How many bytes the handler can receive at one time, when streaming data between local and remote connection.
|
||||
static let maxBytesToRead = Int(UInt16.max)
|
||||
|
||||
@ -20,7 +20,7 @@ struct Socks5DataStreamHandler {
|
||||
let remoteConnection: NWConnection
|
||||
|
||||
/// Error handler.
|
||||
let errorHandler: (Error) -> Void
|
||||
let errorHandler: @Sendable (Error) -> Void
|
||||
|
||||
/// Start streaming data between local and remote connection.
|
||||
func start() {
|
||||
|
@ -10,7 +10,7 @@ import MullvadTypes
|
||||
import Network
|
||||
|
||||
/// A network endpoint specified by DNS name and port.
|
||||
public struct Socks5HostEndpoint {
|
||||
public struct Socks5HostEndpoint: Sendable {
|
||||
/// The endpoint's hostname.
|
||||
public let hostname: String
|
||||
|
||||
@ -43,7 +43,7 @@ public struct Socks5HostEndpoint {
|
||||
}
|
||||
|
||||
/// The endpoint type used by objects implementing socks protocol.
|
||||
public enum Socks5Endpoint {
|
||||
public enum Socks5Endpoint: Sendable {
|
||||
/// IPv4 endpoint.
|
||||
case ipv4(IPv4Endpoint)
|
||||
|
||||
|
@ -10,7 +10,7 @@ import MullvadTypes
|
||||
import Network
|
||||
|
||||
/// The object reading the endpoint data from connection.
|
||||
struct Socks5EndpointReader {
|
||||
struct Socks5EndpointReader: Sendable {
|
||||
/// Connection to the socks proxy.
|
||||
let connection: NWConnection
|
||||
|
||||
@ -18,10 +18,10 @@ struct Socks5EndpointReader {
|
||||
let addressType: Socks5AddressType
|
||||
|
||||
/// Completion handler called upon success.
|
||||
let onComplete: (Socks5Endpoint) -> Void
|
||||
let onComplete: @Sendable (Socks5Endpoint) -> Void
|
||||
|
||||
/// Failure handler.
|
||||
let onFailure: (Error) -> Void
|
||||
let onFailure: @Sendable (Error) -> Void
|
||||
|
||||
/// Start reading endpoint from connection.
|
||||
func perform() {
|
||||
@ -69,7 +69,7 @@ struct Socks5EndpointReader {
|
||||
}
|
||||
}
|
||||
|
||||
private func readBoundDomainNameLength(completion: @escaping (Int) -> Void) {
|
||||
private func readBoundDomainNameLength(completion: @escaping @Sendable (Int) -> Void) {
|
||||
// The length of domain length parameter in bytes.
|
||||
let domainLengthLength = MemoryLayout<UInt8>.size
|
||||
|
||||
|
@ -9,7 +9,7 @@ import Foundation
|
||||
import Network
|
||||
|
||||
/// The errors returned by objects implementing socks proxy.
|
||||
public enum Socks5Error: Error {
|
||||
public enum Socks5Error: Error, Sendable {
|
||||
/// Unexpected end of stream.
|
||||
case unexpectedEndOfStream
|
||||
|
||||
|
@ -19,7 +19,7 @@ import Network
|
||||
|
||||
Refer to RFC1928 for more info on socks5: <https://datatracker.ietf.org/doc/html/rfc1928>
|
||||
*/
|
||||
public final class Socks5ForwardingProxy {
|
||||
public final class Socks5ForwardingProxy: Sendable {
|
||||
/// Socks proxy endpoint.
|
||||
public let socksProxyEndpoint: NWEndpoint
|
||||
|
||||
@ -70,7 +70,7 @@ public final class Socks5ForwardingProxy {
|
||||
- Parameter completion: completion handler that is called once the TCP listener is ready in the first time or failed before moving to the ready state.
|
||||
Invoked on main queue.
|
||||
*/
|
||||
public func start(completion: @escaping (Error?) -> Void) {
|
||||
public func start(completion: @escaping @Sendable (Error?) -> Void) {
|
||||
queue.async {
|
||||
self.startListener { error in
|
||||
DispatchQueue.main.async {
|
||||
@ -85,7 +85,7 @@ public final class Socks5ForwardingProxy {
|
||||
|
||||
- Parameter completion: completion handler that's called immediately after cancelling the TCP listener. Invoked on main queue.
|
||||
*/
|
||||
public func stop(completion: (() -> Void)? = nil) {
|
||||
public func stop(completion: (@Sendable () -> Void)? = nil) {
|
||||
queue.async {
|
||||
self.stopInner()
|
||||
|
||||
@ -100,7 +100,7 @@ public final class Socks5ForwardingProxy {
|
||||
|
||||
- Parameter errorHandler: an error handler block. Invoked on main queue.
|
||||
*/
|
||||
public func setErrorHandler(_ errorHandler: ((Error) -> Void)?) {
|
||||
public func setErrorHandler(_ errorHandler: (@Sendable (Error) -> Void)?) {
|
||||
queue.async {
|
||||
self.errorHandler = errorHandler
|
||||
}
|
||||
@ -108,7 +108,7 @@ public final class Socks5ForwardingProxy {
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private enum State {
|
||||
private enum State: @unchecked Sendable {
|
||||
/// Proxy is starting up.
|
||||
case starting(listener: NWListener, completion: (Error?) -> Void)
|
||||
|
||||
@ -120,15 +120,15 @@ public final class Socks5ForwardingProxy {
|
||||
}
|
||||
|
||||
private let queue = DispatchQueue(label: "Socks5ForwardingProxy-queue")
|
||||
private var state: State = .stopped
|
||||
private var errorHandler: ((Error) -> Void)?
|
||||
nonisolated(unsafe) private var state: State = .stopped
|
||||
nonisolated(unsafe) private var errorHandler: (@Sendable (Error) -> Void)?
|
||||
|
||||
/**
|
||||
Start TCP listener.
|
||||
|
||||
- Parameter completion: completion handler that is called once the TCP listener is ready or failed.
|
||||
*/
|
||||
private func startListener(completion: @escaping (Error?) -> Void) {
|
||||
private func startListener(completion: @escaping @Sendable (Error?) -> Void) {
|
||||
switch state {
|
||||
case .started:
|
||||
completion(nil)
|
||||
|
@ -9,11 +9,11 @@ import Foundation
|
||||
import Network
|
||||
|
||||
/// The object handling a handshake negotiation with socks proxy.
|
||||
struct Socks5HandshakeNegotiation {
|
||||
struct Socks5HandshakeNegotiation: Sendable {
|
||||
let connection: NWConnection
|
||||
let handshake: Socks5Handshake
|
||||
let onComplete: (Socks5HandshakeReply) -> Void
|
||||
let onFailure: (Error) -> Void
|
||||
let onComplete: @Sendable (Socks5HandshakeReply) -> Void
|
||||
let onFailure: @Sendable (Error) -> Void
|
||||
|
||||
func perform() {
|
||||
connection.send(content: handshake.rawData, completion: .contentProcessed { [self] error in
|
||||
|
@ -8,7 +8,7 @@
|
||||
import Foundation
|
||||
|
||||
/// Status code used in socks protocol.
|
||||
public enum Socks5StatusCode: UInt8 {
|
||||
public enum Socks5StatusCode: UInt8, Sendable {
|
||||
case succeeded = 0x00
|
||||
case failure = 0x01
|
||||
case connectionNotAllowedByRuleset = 0x02
|
||||
|
@ -11,7 +11,7 @@ import MullvadLogging
|
||||
import MullvadTypes
|
||||
|
||||
/// Transport that passes URL requests over the local socks forwarding proxy.
|
||||
public class URLSessionSocks5Transport: RESTTransport {
|
||||
public final class URLSessionSocks5Transport: RESTTransport, Sendable {
|
||||
/// Socks5 forwarding proxy.
|
||||
private let socksProxy: Socks5ForwardingProxy
|
||||
|
||||
@ -25,7 +25,7 @@ public class URLSessionSocks5Transport: RESTTransport {
|
||||
"socks5-url-session"
|
||||
}
|
||||
|
||||
private let logger = Logger(label: "URLSessionSocks5Transport")
|
||||
nonisolated(unsafe) private let logger = Logger(label: "URLSessionSocks5Transport")
|
||||
|
||||
/**
|
||||
Instantiates new socks5 transport.
|
||||
@ -57,7 +57,7 @@ public class URLSessionSocks5Transport: RESTTransport {
|
||||
|
||||
public func sendRequest(
|
||||
_ request: URLRequest,
|
||||
completion: @escaping (Data?, URLResponse?, Error?) -> Void
|
||||
completion: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void
|
||||
) -> Cancellable {
|
||||
// Listen port should be set when socks proxy is ready. Otherwise start proxy and only then start the data task.
|
||||
if let localPort = socksProxy.listenPort {
|
||||
@ -70,9 +70,9 @@ public class URLSessionSocks5Transport: RESTTransport {
|
||||
/// Starts socks proxy then executes the data task.
|
||||
private func sendDeferred(
|
||||
request: URLRequest,
|
||||
completion: @escaping (Data?, URLResponse?, Error?) -> Void
|
||||
completion: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void
|
||||
) -> Cancellable {
|
||||
let chain = CancellableChain()
|
||||
nonisolated(unsafe) let chain = CancellableChain()
|
||||
|
||||
socksProxy.start { [weak self, weak socksProxy] error in
|
||||
if let error {
|
||||
@ -94,7 +94,7 @@ public class URLSessionSocks5Transport: RESTTransport {
|
||||
private func startDataTask(
|
||||
request: URLRequest,
|
||||
localPort: UInt16,
|
||||
completion: @escaping (Data?, URLResponse?, Error?) -> Void
|
||||
completion: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void
|
||||
) -> Cancellable {
|
||||
// Copy the URL request and rewrite the host and port to point to the socks5 forwarding proxy instance
|
||||
var newRequest = request
|
||||
|
@ -10,12 +10,12 @@ import Foundation
|
||||
import Logging
|
||||
import MullvadTypes
|
||||
|
||||
public final class TransportProvider: RESTTransportProvider {
|
||||
public final class TransportProvider: RESTTransportProvider, Sendable {
|
||||
private let urlSessionTransport: URLSessionTransport
|
||||
private let addressCache: REST.AddressCache
|
||||
private var transportStrategy: TransportStrategy
|
||||
private var currentTransport: RESTTransport?
|
||||
private var currentTransportType: TransportStrategy.Transport
|
||||
nonisolated(unsafe) private var transportStrategy: TransportStrategy
|
||||
nonisolated(unsafe) private var currentTransport: RESTTransport?
|
||||
nonisolated(unsafe) private var currentTransportType: TransportStrategy.Transport
|
||||
private let parallelRequestsMutex = NSLock()
|
||||
private let encryptedDNSTransport: RESTTransport
|
||||
|
||||
@ -123,7 +123,7 @@ private extension URLError {
|
||||
/// Interstitial implementation of `RESTTransport` that intercepts the completion of the wrapped transport.
|
||||
private struct TransportWrapper: RESTTransport {
|
||||
let wrapped: RESTTransport
|
||||
let onComplete: (Error?) -> Void
|
||||
let onComplete: @Sendable (Error?) -> Void
|
||||
|
||||
var name: String {
|
||||
return wrapped.name
|
||||
@ -131,7 +131,7 @@ private struct TransportWrapper: RESTTransport {
|
||||
|
||||
func sendRequest(
|
||||
_ request: URLRequest,
|
||||
completion: @escaping (Data?, URLResponse?, Error?) -> Void
|
||||
completion: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void
|
||||
) -> Cancellable {
|
||||
return wrapped.sendRequest(request) { data, response, error in
|
||||
onComplete(error)
|
||||
|
@ -11,7 +11,7 @@ import Logging
|
||||
import MullvadSettings
|
||||
import MullvadTypes
|
||||
|
||||
public struct TransportStrategy: Equatable {
|
||||
public struct TransportStrategy: Equatable, Sendable {
|
||||
/// The different transports suggested by the strategy
|
||||
public enum Transport: Equatable {
|
||||
/// Connecting a direct connection
|
||||
|
@ -6,12 +6,12 @@
|
||||
// Copyright © 2023 Mullvad VPN AB. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@preconcurrency import Foundation
|
||||
@testable import MullvadREST
|
||||
import MullvadTypes
|
||||
|
||||
/// Mock implementation of REST transport that can be used to handle requests without doing any actual networking.
|
||||
class AnyTransport: RESTTransport {
|
||||
class AnyTransport: RESTTransport, @unchecked Sendable {
|
||||
typealias CompletionHandler = (Data?, URLResponse?, Error?) -> Void
|
||||
|
||||
private let handleRequest: () -> AnyResponse
|
||||
@ -19,7 +19,7 @@ class AnyTransport: RESTTransport {
|
||||
private let completionLock = NSLock()
|
||||
private var completionHandlers: [UUID: CompletionHandler] = [:]
|
||||
|
||||
init(block: @escaping () -> AnyResponse) {
|
||||
init(block: @escaping @Sendable () -> AnyResponse) {
|
||||
handleRequest = block
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ class AnyTransport: RESTTransport {
|
||||
|
||||
func sendRequest(
|
||||
_ request: URLRequest,
|
||||
completion: @escaping (Data?, URLResponse?, Error?) -> Void
|
||||
completion: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void
|
||||
) -> Cancellable {
|
||||
let response = handleRequest()
|
||||
let id = storeCompletion(completionHandler: completion)
|
||||
|
@ -19,7 +19,7 @@ struct RESTTransportStub: RESTTransport {
|
||||
|
||||
func sendRequest(
|
||||
_ request: URLRequest,
|
||||
completion: @escaping (Data?, URLResponse?, Error?) -> Void
|
||||
completion: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void
|
||||
) -> Cancellable {
|
||||
completion(data, response, error)
|
||||
return AnyCancellable()
|
||||
|
@ -10,7 +10,7 @@ import Foundation
|
||||
@testable import MullvadREST
|
||||
|
||||
/// Simple API proxy used for testing purposes.
|
||||
final class TimeServerProxy: REST.Proxy<REST.ProxyConfiguration> {
|
||||
final class TimeServerProxy: REST.Proxy<REST.ProxyConfiguration>, @unchecked Sendable {
|
||||
init(configuration: REST.ProxyConfiguration) {
|
||||
super.init(
|
||||
name: "TimeServerProxy",
|
||||
|
@ -11,9 +11,10 @@
|
||||
@testable import MullvadTypes
|
||||
import XCTest
|
||||
|
||||
@MainActor
|
||||
final class RequestExecutorTests: XCTestCase {
|
||||
let addressCache = REST.AddressCache(canWriteToCache: false, fileCache: MemoryCache())
|
||||
var timerServerProxy: TimeServerProxy!
|
||||
nonisolated(unsafe) var timerServerProxy: TimeServerProxy!
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
|
@ -11,7 +11,7 @@ import MullvadRustRuntimeProxy
|
||||
import Network
|
||||
|
||||
/// A Swift wrapper around a Rust implementation of Shadowsocks proxy instance
|
||||
public class ShadowsocksProxy {
|
||||
public class ShadowsocksProxy: @unchecked Sendable {
|
||||
private var proxyConfig: ProxyHandle
|
||||
private let forwardAddress: IPAddress
|
||||
private let forwardPort: UInt16
|
||||
|
@ -9,7 +9,7 @@
|
||||
import Network
|
||||
|
||||
/// > Warning: Do not use this implementation in production code. See the warning in `start()`.
|
||||
class UnsafeListener<T: Connection> {
|
||||
class UnsafeListener<T: Connection>: @unchecked Sendable {
|
||||
private let dispatchQueue = DispatchQueue(label: "com.test.unsafeListener")
|
||||
private let listener: NWListener
|
||||
|
||||
|
@ -11,7 +11,7 @@ import Foundation
|
||||
import MullvadLogging
|
||||
import MullvadTypes
|
||||
|
||||
public class AccessMethodRepository: AccessMethodRepositoryProtocol {
|
||||
public class AccessMethodRepository: AccessMethodRepositoryProtocol, @unchecked Sendable {
|
||||
public static let directId = UUID(uuidString: "C9DB7457-2A55-42C3-A926-C07F82131994")!
|
||||
public static let bridgeId = UUID(uuidString: "8586E75A-CA7B-4432-B70D-EE65F3F95084")!
|
||||
public static let encryptedDNSId = UUID(uuidString: "831CB1F8-1829-42DD-B9DC-82902F298EC0")!
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Combine
|
||||
|
||||
public protocol AccessMethodRepositoryDataSource {
|
||||
public protocol AccessMethodRepositoryDataSource: Sendable {
|
||||
/// Publisher that propagates a snapshot of all access methods upon modifications.
|
||||
var accessMethodsPublisher: AnyPublisher<[PersistentAccessMethod], Never> { get }
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
import Foundation
|
||||
|
||||
/// Whether DAITA is enabled.
|
||||
public enum DAITAState: Codable {
|
||||
public enum DAITAState: Codable, Sendable {
|
||||
case on
|
||||
case off
|
||||
|
||||
@ -24,7 +24,7 @@ public enum DAITAState: Codable {
|
||||
}
|
||||
|
||||
/// Whether "direct only" is enabled, meaning no automatic routing to DAITA relays.
|
||||
public enum DirectOnlyState: Codable {
|
||||
public enum DirectOnlyState: Codable, Sendable {
|
||||
case on
|
||||
case off
|
||||
|
||||
@ -43,7 +43,7 @@ public enum DAITASettingsCompatibilityError {
|
||||
case singlehop, multihop
|
||||
}
|
||||
|
||||
public struct DAITASettings: Codable, Equatable {
|
||||
public struct DAITASettings: Codable, Equatable, Sendable {
|
||||
@available(*, deprecated, renamed: "daitaState")
|
||||
public let state: DAITAState = .off
|
||||
|
||||
|
@ -11,7 +11,7 @@ import MullvadTypes
|
||||
import Network
|
||||
|
||||
/// A struct describing Mullvad DNS blocking options.
|
||||
public struct DNSBlockingOptions: OptionSet, Codable {
|
||||
public struct DNSBlockingOptions: OptionSet, Codable, Sendable {
|
||||
public let rawValue: UInt32
|
||||
|
||||
public static let blockAdvertising = DNSBlockingOptions(rawValue: 1 << 0)
|
||||
@ -48,7 +48,7 @@ public struct DNSBlockingOptions: OptionSet, Codable {
|
||||
}
|
||||
|
||||
/// A struct that holds DNS settings.
|
||||
public struct DNSSettings: Codable, Equatable {
|
||||
public struct DNSSettings: Codable, Equatable, Sendable {
|
||||
/// Maximum number of allowed DNS domains.
|
||||
public static let maxAllowedCustomDNSDomains = 3
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum DeviceState: Codable, Equatable {
|
||||
public enum DeviceState: Codable, Equatable, Sendable {
|
||||
case loggedIn(StoredAccountData, StoredDeviceData)
|
||||
case loggedOut
|
||||
case revoked
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Network
|
||||
|
||||
public struct RelayOverrides: Codable {
|
||||
public struct RelayOverrides: Codable, Sendable {
|
||||
public let overrides: [IPOverride]
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
@ -20,7 +20,7 @@ public struct IPOverrideFormatError: LocalizedError {
|
||||
public let errorDescription: String?
|
||||
}
|
||||
|
||||
public struct IPOverride: Codable, Equatable {
|
||||
public struct IPOverride: Codable, Equatable, Sendable {
|
||||
public let hostname: String
|
||||
public var ipv4Address: IPv4Address?
|
||||
public var ipv6Address: IPv6Address?
|
||||
|
@ -6,10 +6,10 @@
|
||||
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
|
||||
//
|
||||
|
||||
import Combine
|
||||
@preconcurrency import Combine
|
||||
import MullvadLogging
|
||||
|
||||
public protocol IPOverrideRepositoryProtocol {
|
||||
public protocol IPOverrideRepositoryProtocol: Sendable {
|
||||
var overridesPublisher: AnyPublisher<[IPOverride], Never> { get }
|
||||
func add(_ overrides: [IPOverride])
|
||||
func fetchAll() -> [IPOverride]
|
||||
@ -17,13 +17,13 @@ public protocol IPOverrideRepositoryProtocol {
|
||||
func parse(data: Data) throws -> [IPOverride]
|
||||
}
|
||||
|
||||
public class IPOverrideRepository: IPOverrideRepositoryProtocol {
|
||||
public final class IPOverrideRepository: IPOverrideRepositoryProtocol {
|
||||
private let overridesSubject: CurrentValueSubject<[IPOverride], Never> = .init([])
|
||||
public var overridesPublisher: AnyPublisher<[IPOverride], Never> {
|
||||
overridesSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
private let logger = Logger(label: "IPOverrideRepository")
|
||||
nonisolated(unsafe) private let logger = Logger(label: "IPOverrideRepository")
|
||||
private let readWriteLock = NSLock()
|
||||
|
||||
public init() {}
|
||||
|
@ -10,7 +10,7 @@ import Foundation
|
||||
import MullvadTypes
|
||||
import Security
|
||||
|
||||
public class KeychainSettingsStore: SettingsStore {
|
||||
final public class KeychainSettingsStore: SettingsStore, Sendable {
|
||||
public let serviceName: String
|
||||
public let accessGroup: String
|
||||
|
||||
|
@ -12,6 +12,6 @@ public protocol Migration {
|
||||
func migrate(
|
||||
with store: SettingsStore,
|
||||
parser: SettingsParser,
|
||||
completion: @escaping (Error?) -> Void
|
||||
completion: @escaping @Sendable (Error?) -> Void
|
||||
)
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import Foundation
|
||||
import MullvadLogging
|
||||
import MullvadTypes
|
||||
|
||||
public enum SettingsMigrationResult {
|
||||
public enum SettingsMigrationResult: Sendable {
|
||||
/// Nothing to migrate.
|
||||
case nothing
|
||||
|
||||
@ -42,7 +42,7 @@ public struct MigrationManager {
|
||||
/// - migrationCompleted: Completion handler called with a migration result.
|
||||
public func migrateSettings(
|
||||
store: SettingsStore,
|
||||
migrationCompleted: @escaping (SettingsMigrationResult) -> Void
|
||||
migrationCompleted: @escaping @Sendable (SettingsMigrationResult) -> Void
|
||||
) {
|
||||
let fileCoordinator = NSFileCoordinator(filePresenter: nil)
|
||||
var error: NSError?
|
||||
@ -79,7 +79,7 @@ public struct MigrationManager {
|
||||
|
||||
private func upgradeSettingsToLatestVersion(
|
||||
store: SettingsStore,
|
||||
migrationCompleted: @escaping (SettingsMigrationResult) -> Void
|
||||
migrationCompleted: @escaping @Sendable (SettingsMigrationResult) -> Void
|
||||
) throws {
|
||||
let parser = SettingsParser(decoder: JSONDecoder(), encoder: JSONEncoder())
|
||||
let settingsData = try store.read(key: SettingsKey.settings)
|
||||
|
@ -9,8 +9,8 @@
|
||||
import Foundation
|
||||
import MullvadTypes
|
||||
|
||||
/// Whether multihop is enabled.
|
||||
public enum MultihopState: Codable {
|
||||
/// Whether Multi-hop is enabled
|
||||
public enum MultihopState: Codable, Sendable {
|
||||
case on
|
||||
case off
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum TunnelQuantumResistance: Codable {
|
||||
public enum TunnelQuantumResistance: Codable, Sendable {
|
||||
case automatic
|
||||
case on
|
||||
case off
|
||||
|
@ -15,16 +15,16 @@ private let accountTokenKey = "accountToken"
|
||||
private let accountExpiryKey = "accountExpiry"
|
||||
|
||||
public enum SettingsManager {
|
||||
private static let logger = Logger(label: "SettingsManager")
|
||||
nonisolated(unsafe) private static let logger = Logger(label: "SettingsManager")
|
||||
|
||||
#if DEBUG
|
||||
private static var _store = KeychainSettingsStore(
|
||||
nonisolated(unsafe) private static var _store = KeychainSettingsStore(
|
||||
serviceName: keychainServiceName,
|
||||
accessGroup: ApplicationConfiguration.securityGroupIdentifier
|
||||
)
|
||||
|
||||
/// Alternative store used for tests.
|
||||
internal static var unitTestStore: SettingsStore?
|
||||
nonisolated(unsafe) internal static var unitTestStore: SettingsStore?
|
||||
|
||||
public static var store: SettingsStore {
|
||||
if let unitTestStore { return unitTestStore }
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum SettingsKey: String, CaseIterable {
|
||||
public enum SettingsKey: String, CaseIterable, Sendable {
|
||||
case settings = "Settings"
|
||||
case deviceState = "DeviceState"
|
||||
case apiAccessMethods = "ApiAccessMethods"
|
||||
@ -18,7 +18,7 @@ public enum SettingsKey: String, CaseIterable {
|
||||
case shouldWipeSettings = "ShouldWipeSettings"
|
||||
}
|
||||
|
||||
public protocol SettingsStore {
|
||||
public protocol SettingsStore: Sendable {
|
||||
func read(key: SettingsKey) throws -> Data
|
||||
func write(_ data: Data, for key: SettingsKey) throws
|
||||
func delete(key: SettingsKey) throws
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct ShadowsocksCipherOptions: RawRepresentable, Codable, Hashable {
|
||||
public struct ShadowsocksCipherOptions: RawRepresentable, Codable, Hashable, Sendable {
|
||||
public let rawValue: CipherIdentifiers
|
||||
|
||||
public init(rawValue: CipherIdentifiers) {
|
||||
@ -22,7 +22,7 @@ public struct ShadowsocksCipherOptions: RawRepresentable, Codable, Hashable {
|
||||
public static let all = CipherIdentifiers.allCases.map { ShadowsocksCipherOptions(rawValue: $0) }
|
||||
}
|
||||
|
||||
public enum CipherIdentifiers: String, CaseIterable, CustomStringConvertible, Codable {
|
||||
public enum CipherIdentifiers: String, CaseIterable, CustomStringConvertible, Codable, Sendable {
|
||||
// Stream ciphers.
|
||||
case CFB_AES128 = "aes-128-cfb"
|
||||
case CFB1_AES128 = "aes-128-cfb1"
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct StoredAccountData: Codable, Equatable {
|
||||
public struct StoredAccountData: Codable, Equatable, Sendable {
|
||||
/// Account identifier.
|
||||
public var identifier: String
|
||||
|
||||
|
@ -8,9 +8,9 @@
|
||||
|
||||
import Foundation
|
||||
import MullvadTypes
|
||||
import WireGuardKitTypes
|
||||
@preconcurrency import WireGuardKitTypes
|
||||
|
||||
public struct StoredDeviceData: Codable, Equatable {
|
||||
public struct StoredDeviceData: Codable, Equatable, Sendable {
|
||||
/// Device creation date.
|
||||
public var creationDate: Date
|
||||
|
||||
|
@ -7,9 +7,9 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import WireGuardKitTypes
|
||||
@preconcurrency import WireGuardKitTypes
|
||||
|
||||
public struct StoredWgKeyData: Codable, Equatable {
|
||||
public struct StoredWgKeyData: Codable, Equatable, Sendable {
|
||||
/// Private key creation date.
|
||||
public var creationDate: Date
|
||||
|
||||
|
@ -12,12 +12,12 @@ import Foundation
|
||||
public typealias LatestTunnelSettings = TunnelSettingsV6
|
||||
|
||||
/// Protocol all TunnelSettings must adhere to, for upgrade purposes.
|
||||
public protocol TunnelSettings: Codable {
|
||||
public protocol TunnelSettings: Codable, Sendable {
|
||||
func upgradeToNextVersion() -> any TunnelSettings
|
||||
}
|
||||
|
||||
/// Settings and device state schema versions.
|
||||
public enum SchemaVersion: Int, Equatable {
|
||||
public enum SchemaVersion: Int, Equatable, Sendable {
|
||||
/// Legacy settings format, stored as `TunnelSettingsV1`.
|
||||
case v1 = 1
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import MullvadTypes
|
||||
|
||||
public protocol SettingsPropagation {
|
||||
public protocol SettingsPropagation: Sendable {
|
||||
typealias SettingsHandler = (LatestTunnelSettings) -> Void
|
||||
var onNewSettings: SettingsHandler? { get set }
|
||||
}
|
||||
@ -30,7 +30,7 @@ public class SettingsObserverBlock: SettingsObserver {
|
||||
}
|
||||
}
|
||||
|
||||
public final class TunnelSettingsListener: SettingsPropagation {
|
||||
public final class TunnelSettingsListener: SettingsPropagation, @unchecked Sendable {
|
||||
public var onNewSettings: SettingsHandler?
|
||||
|
||||
public init(onNewSettings: SettingsHandler? = nil) {
|
||||
@ -38,10 +38,10 @@ public final class TunnelSettingsListener: SettingsPropagation {
|
||||
}
|
||||
}
|
||||
|
||||
public class SettingsUpdater {
|
||||
public final class SettingsUpdater: Sendable {
|
||||
/// Observers.
|
||||
private let observerList = ObserverList<SettingsObserver>()
|
||||
private var listener: SettingsPropagation
|
||||
nonisolated(unsafe) private var listener: SettingsPropagation
|
||||
|
||||
public init(listener: SettingsPropagation) {
|
||||
self.listener = listener
|
||||
|
@ -7,11 +7,11 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
public protocol TunnelSettingsStrategyProtocol {
|
||||
public protocol TunnelSettingsStrategyProtocol: Sendable {
|
||||
func shouldReconnectToNewRelay(oldSettings: LatestTunnelSettings, newSettings: LatestTunnelSettings) -> Bool
|
||||
}
|
||||
|
||||
public struct TunnelSettingsStrategy: TunnelSettingsStrategyProtocol {
|
||||
public struct TunnelSettingsStrategy: TunnelSettingsStrategyProtocol, Sendable {
|
||||
public init() {}
|
||||
public func shouldReconnectToNewRelay(
|
||||
oldSettings: LatestTunnelSettings,
|
||||
|
@ -9,7 +9,7 @@
|
||||
import Foundation
|
||||
import MullvadTypes
|
||||
|
||||
public enum TunnelSettingsUpdate {
|
||||
public enum TunnelSettingsUpdate: Sendable {
|
||||
case dnsSettings(DNSSettings)
|
||||
case obfuscation(WireGuardObfuscationSettings)
|
||||
case relayConstraints(RelayConstraints)
|
||||
|
@ -22,7 +22,7 @@ public struct TunnelSettingsV1: Codable, Equatable, TunnelSettings {
|
||||
}
|
||||
|
||||
/// A struct that holds a tun interface configuration.
|
||||
public struct InterfaceSettings: Codable, Equatable {
|
||||
public struct InterfaceSettings: Codable, Equatable, @unchecked Sendable {
|
||||
public var privateKey: PrivateKeyWithMetadata
|
||||
public var nextPrivateKey: PrivateKeyWithMetadata?
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
import Foundation
|
||||
import MullvadTypes
|
||||
|
||||
public struct TunnelSettingsV6: Codable, Equatable, TunnelSettings {
|
||||
public struct TunnelSettingsV6: Codable, Equatable, TunnelSettings, Sendable {
|
||||
/// Relay constraints.
|
||||
public var relayConstraints: RelayConstraints
|
||||
|
||||
|
@ -11,7 +11,7 @@ import Foundation
|
||||
/// Whether obfuscation is enabled and which method is used.
|
||||
///
|
||||
/// `.automatic` means an algorithm will decide whether to use obfuscation or not.
|
||||
public enum WireGuardObfuscationState: Codable {
|
||||
public enum WireGuardObfuscationState: Codable, Sendable {
|
||||
@available(*, deprecated, renamed: "udpOverTcp")
|
||||
case on
|
||||
|
||||
@ -52,7 +52,7 @@ public enum WireGuardObfuscationState: Codable {
|
||||
}
|
||||
}
|
||||
|
||||
public enum WireGuardObfuscationUdpOverTcpPort: Codable, Equatable, CustomStringConvertible {
|
||||
public enum WireGuardObfuscationUdpOverTcpPort: Codable, Equatable, CustomStringConvertible, Sendable {
|
||||
case automatic
|
||||
case port80
|
||||
case port5001
|
||||
@ -85,7 +85,7 @@ public enum WireGuardObfuscationUdpOverTcpPort: Codable, Equatable, CustomString
|
||||
}
|
||||
}
|
||||
|
||||
public enum WireGuardObfuscationShadowsocksPort: Codable, Equatable, CustomStringConvertible {
|
||||
public enum WireGuardObfuscationShadowsocksPort: Codable, Equatable, CustomStringConvertible, Sendable {
|
||||
case automatic
|
||||
case custom(UInt16)
|
||||
|
||||
@ -115,7 +115,7 @@ public enum WireGuardObfuscationShadowsocksPort: Codable, Equatable, CustomStrin
|
||||
|
||||
// Can't deprecate the whole type since it'll yield a lint warning when decoding
|
||||
// port in `WireGuardObfuscationSettings`.
|
||||
private enum WireGuardObfuscationPort: UInt16, Codable {
|
||||
private enum WireGuardObfuscationPort: UInt16, Codable, Sendable {
|
||||
@available(*, deprecated, message: "Use `udpOverTcpPort` instead")
|
||||
case automatic = 0
|
||||
@available(*, deprecated, message: "Use `udpOverTcpPort` instead")
|
||||
@ -124,7 +124,7 @@ private enum WireGuardObfuscationPort: UInt16, Codable {
|
||||
case port5001 = 5001
|
||||
}
|
||||
|
||||
public struct WireGuardObfuscationSettings: Codable, Equatable {
|
||||
public struct WireGuardObfuscationSettings: Codable, Equatable, Sendable {
|
||||
@available(*, deprecated, message: "Use `udpOverTcpPort` instead")
|
||||
private var port: WireGuardObfuscationPort = .automatic
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
import Foundation
|
||||
import protocol Network.IPAddress
|
||||
|
||||
public enum AnyIPEndpoint: Hashable, Equatable, Codable, CustomStringConvertible {
|
||||
public enum AnyIPEndpoint: Hashable, Equatable, Codable, CustomStringConvertible, @unchecked Sendable {
|
||||
case ipv4(IPv4Endpoint)
|
||||
case ipv6(IPv6Endpoint)
|
||||
|
||||
|
@ -19,7 +19,7 @@ public final class AnyCancellable: Cancellable {
|
||||
private let block: (() -> Void)?
|
||||
|
||||
/// Create cancellation token with block handler.
|
||||
public init(block: @escaping () -> Void) {
|
||||
public init(block: @escaping @Sendable () -> Void) {
|
||||
self.block = block
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
import Foundation
|
||||
import Network
|
||||
|
||||
public struct IPv4Endpoint: Hashable, Equatable, Codable, CustomStringConvertible {
|
||||
public struct IPv4Endpoint: Hashable, Equatable, Codable, CustomStringConvertible, Sendable {
|
||||
public let ip: IPv4Address
|
||||
public let port: UInt16
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
import Foundation
|
||||
import Network
|
||||
|
||||
public struct IPv6Endpoint: Hashable, Equatable, Codable, CustomStringConvertible {
|
||||
public struct IPv6Endpoint: Hashable, Equatable, Codable, CustomStringConvertible, Sendable {
|
||||
public let ip: IPv6Address
|
||||
public let port: UInt16
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
import CoreLocation
|
||||
import Foundation
|
||||
|
||||
public struct Location: Codable, Equatable {
|
||||
public struct Location: Codable, Equatable, Sendable {
|
||||
public var country: String
|
||||
public var countryCode: String
|
||||
public var city: String
|
||||
|
@ -10,7 +10,7 @@ import Foundation
|
||||
import Network
|
||||
|
||||
/// Contains server data needed to connect to a single mullvad endpoint.
|
||||
public struct MullvadEndpoint: Equatable, Codable {
|
||||
public struct MullvadEndpoint: Equatable, Codable, Sendable {
|
||||
public let ipv4Relay: IPv4Endpoint
|
||||
public let ipv6Relay: IPv6Endpoint?
|
||||
public let ipv4Gateway: IPv4Address
|
||||
|
@ -8,12 +8,12 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct WeakBox<T> {
|
||||
public struct WeakBox<T>: Sendable {
|
||||
public var value: T? {
|
||||
valueProvider()
|
||||
}
|
||||
|
||||
private let valueProvider: () -> T?
|
||||
nonisolated(unsafe) private let valueProvider: () -> T?
|
||||
|
||||
public init(_ value: T) {
|
||||
let reference = value as AnyObject
|
||||
@ -28,9 +28,9 @@ public struct WeakBox<T> {
|
||||
}
|
||||
}
|
||||
|
||||
final public class ObserverList<T> {
|
||||
final public class ObserverList<T>: Sendable {
|
||||
private let lock = NSLock()
|
||||
private var observers = [WeakBox<T>]()
|
||||
nonisolated(unsafe) private var observers = [WeakBox<T>]()
|
||||
|
||||
public init() {}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public final class Promise<Success, Failure: Error> {
|
||||
public final class Promise<Success, Failure: Error>: @unchecked Sendable {
|
||||
public typealias Result = Swift.Result<Success, Failure>
|
||||
|
||||
private let nslock = NSLock()
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct DaitaV2Parameters: Equatable {
|
||||
public struct DaitaV2Parameters: Equatable, Sendable {
|
||||
public let machines: String
|
||||
public let maximumEvents: UInt32
|
||||
public let maximumActions: UInt32
|
||||
|
@ -0,0 +1,17 @@
|
||||
//
|
||||
// NetworkExtension+HiddenSymbols.swift
|
||||
// MullvadTypes
|
||||
//
|
||||
// Created by Marco Nikic on 2024-12-04.
|
||||
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import NetworkExtension
|
||||
|
||||
#if swift(>=6)
|
||||
#if compiler(>=6)
|
||||
public typealias NWTCPConnection = __NWTCPConnection
|
||||
public typealias NWHostEndpoint = __NWHostEndpoint
|
||||
#endif
|
||||
#endif
|
@ -7,9 +7,9 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import WireGuardKitTypes
|
||||
@preconcurrency import WireGuardKitTypes
|
||||
|
||||
public struct Account: Codable, Equatable {
|
||||
public struct Account: Codable, Equatable, Sendable {
|
||||
public let id: String
|
||||
public let expiry: Date
|
||||
public let maxDevices: Int
|
||||
@ -23,7 +23,7 @@ public struct Account: Codable, Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
public struct Device: Codable, Equatable {
|
||||
public struct Device: Codable, Equatable, Sendable {
|
||||
public let id: String
|
||||
public let name: String
|
||||
public let pubkey: PublicKey
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct RelayConstraints: Codable, Equatable, CustomDebugStringConvertible {
|
||||
public struct RelayConstraints: Codable, Equatable, CustomDebugStringConvertible, @unchecked Sendable {
|
||||
@available(*, deprecated, renamed: "locations")
|
||||
private var location: RelayConstraint<RelayLocation> = .only(.country("se"))
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum RelayLocation: Codable, Hashable, CustomDebugStringConvertible {
|
||||
public enum RelayLocation: Codable, Hashable, CustomDebugStringConvertible, Sendable {
|
||||
case country(String)
|
||||
case city(String, String)
|
||||
case hostname(String, String, String)
|
||||
@ -107,7 +107,7 @@ public enum RelayLocation: Codable, Hashable, CustomDebugStringConvertible {
|
||||
}
|
||||
}
|
||||
|
||||
public struct UserSelectedRelays: Codable, Equatable {
|
||||
public struct UserSelectedRelays: Codable, Equatable, Sendable {
|
||||
public let locations: [RelayLocation]
|
||||
public let customListSelection: CustomListSelection?
|
||||
|
||||
@ -118,7 +118,7 @@ public struct UserSelectedRelays: Codable, Equatable {
|
||||
}
|
||||
|
||||
extension UserSelectedRelays {
|
||||
public struct CustomListSelection: Codable, Equatable {
|
||||
public struct CustomListSelection: Codable, Equatable, Sendable {
|
||||
/// The ID of the custom list that the selected relays belong to.
|
||||
public let listId: UUID
|
||||
/// Whether the selected relays are subnodes or the custom list itself.
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum TransportLayer: Codable {
|
||||
public enum TransportLayer: Codable, Sendable {
|
||||
case udp
|
||||
case tcp
|
||||
}
|
||||
|
@ -1321,6 +1321,13 @@
|
||||
remoteGlobalIDString = 58D223D4294C8E5E0029F5F8;
|
||||
remoteInfo = MullvadTypes;
|
||||
};
|
||||
A9609B6D2D004D1F0065A3D3 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 58CE5E58224146200008646E /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 58FBDA9722A519BC00EB69A3;
|
||||
remoteInfo = WireGuardGoBridge;
|
||||
};
|
||||
A992DA212C24709F00DE7CE5 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 58CE5E58224146200008646E /* Project object */;
|
||||
@ -4837,6 +4844,7 @@
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
A9609B6E2D004D1F0065A3D3 /* PBXTargetDependency */,
|
||||
58D223E9294C8F120029F5F8 /* PBXTargetDependency */,
|
||||
58D223F8294C8FF00029F5F8 /* PBXTargetDependency */,
|
||||
06799AD028F98E1D00ACD94E /* PBXTargetDependency */,
|
||||
@ -6754,6 +6762,11 @@
|
||||
target = 58D223D4294C8E5E0029F5F8 /* MullvadTypes */;
|
||||
targetProxy = A9173C332C36CCFB00F6A08C /* PBXContainerItemProxy */;
|
||||
};
|
||||
A9609B6E2D004D1F0065A3D3 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 58FBDA9722A519BC00EB69A3 /* WireGuardGoBridge */;
|
||||
targetProxy = A9609B6D2D004D1F0065A3D3 /* PBXContainerItemProxy */;
|
||||
};
|
||||
A992DA222C24709F00DE7CE5 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = A992DA1C2C24709F00DE7CE5 /* MullvadRustRuntime */;
|
||||
@ -6919,6 +6932,7 @@
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
@ -6938,6 +6952,7 @@
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
@ -7048,6 +7063,7 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
@ -7087,6 +7103,7 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
@ -7109,6 +7126,7 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
@ -7129,6 +7147,7 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
@ -7192,7 +7211,7 @@
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_PRECOMPILE_BRIDGING_HEADER = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
SWIFT_VERSION = 6.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
@ -7250,7 +7269,7 @@
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_PRECOMPILE_BRIDGING_HEADER = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
SWIFT_VERSION = 6.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
@ -7328,6 +7347,7 @@
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_STRICT_CONCURRENCY = minimal;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@ -7347,6 +7367,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(APPLICATION_IDENTIFIER).PacketTunnel";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_STRICT_CONCURRENCY = minimal;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@ -7448,6 +7469,7 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
@ -7483,6 +7505,7 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
@ -7570,7 +7593,7 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
PATH = "${PATH}:/opt/homebrew/opt/go@1.19/bin";
|
||||
PATH = "${PATH}:/opt/homebrew/opt/go@1.21/bin";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
@ -7583,7 +7606,7 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
PATH = "${PATH}:/opt/homebrew/opt/go@1.19/bin";
|
||||
PATH = "${PATH}:/opt/homebrew/opt/go@1.21/bin";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
@ -7894,7 +7917,7 @@
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_PRECOMPILE_BRIDGING_HEADER = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
SWIFT_VERSION = 6.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Staging;
|
||||
@ -7938,7 +7961,7 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
PATH = "${PATH}:/opt/homebrew/opt/go@1.19/bin";
|
||||
PATH = "${PATH}:/opt/homebrew/opt/go@1.21/bin";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Staging;
|
||||
@ -7963,6 +7986,7 @@
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Packet Tunnel Development";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_STRICT_CONCURRENCY = minimal;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Staging;
|
||||
};
|
||||
@ -7981,6 +8005,7 @@
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Staging;
|
||||
@ -8126,6 +8151,7 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
@ -8198,6 +8224,7 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
@ -8220,6 +8247,7 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Staging;
|
||||
@ -8424,6 +8452,7 @@
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
@ -8474,6 +8503,7 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
@ -8524,6 +8554,7 @@
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
@ -8573,6 +8604,7 @@
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
@ -8600,6 +8632,7 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
@ -8624,6 +8657,7 @@
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Staging;
|
||||
@ -8648,6 +8682,7 @@
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
@ -8672,6 +8707,7 @@
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = MockRelease;
|
||||
@ -8728,7 +8764,7 @@
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_PRECOMPILE_BRIDGING_HEADER = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
SWIFT_VERSION = 6.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
@ -8769,7 +8805,7 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
PATH = "${PATH}:/opt/homebrew/opt/go@1.19/bin";
|
||||
PATH = "${PATH}:/opt/homebrew/opt/go@1.21/bin";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = MockRelease;
|
||||
@ -8793,6 +8829,7 @@
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Packet Tunnel Development";
|
||||
SWIFT_STRICT_CONCURRENCY = minimal;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = MockRelease;
|
||||
};
|
||||
@ -8811,6 +8848,7 @@
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = MockRelease;
|
||||
@ -8956,6 +8994,7 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
@ -9028,6 +9067,7 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
@ -9050,6 +9090,7 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = MockRelease;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user