Enable compilation with Swift 6 for most targets

This commit is contained in:
Bug Magnet 2024-12-04 14:43:23 +01:00
parent d2949b4a0b
commit d1cf679456
No known key found for this signature in database
GPG Key ID: 61ACDF76ADB76D73
297 changed files with 1119 additions and 867 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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> {

View File

@ -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 {

View File

@ -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,

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}
}

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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")

View File

@ -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>

View File

@ -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(

View File

@ -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.

View File

@ -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

View File

@ -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()

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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? {

View File

@ -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) {

View File

@ -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

View File

@ -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) {

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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()
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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>

View File

@ -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 {

View File

@ -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?

View File

@ -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()

View File

@ -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)
}
}

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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() {

View File

@ -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)
}

View File

@ -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() {

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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",

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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")!

View File

@ -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 }

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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?

View File

@ -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() {}

View File

@ -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

View File

@ -12,6 +12,6 @@ public protocol Migration {
func migrate(
with store: SettingsStore,
parser: SettingsParser,
completion: @escaping (Error?) -> Void
completion: @escaping @Sendable (Error?) -> Void
)
}

View File

@ -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)

View File

@ -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

View File

@ -8,7 +8,7 @@
import Foundation
public enum TunnelQuantumResistance: Codable {
public enum TunnelQuantumResistance: Codable, Sendable {
case automatic
case on
case off

View File

@ -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 }

View File

@ -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

View File

@ -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"

View File

@ -8,7 +8,7 @@
import Foundation
public struct StoredAccountData: Codable, Equatable {
public struct StoredAccountData: Codable, Equatable, Sendable {
/// Account identifier.
public var identifier: String

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -9,7 +9,7 @@
import Foundation
import MullvadTypes
public enum TunnelSettingsUpdate {
public enum TunnelSettingsUpdate: Sendable {
case dnsSettings(DNSSettings)
case obfuscation(WireGuardObfuscationSettings)
case relayConstraints(RelayConstraints)

View File

@ -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?

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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() {}

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"))

View File

@ -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.

View File

@ -8,7 +8,7 @@
import Foundation
public enum TransportLayer: Codable {
public enum TransportLayer: Codable, Sendable {
case udp
case tcp
}

View File

@ -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