Skip to content

Commit 758e217

Browse files
author
Jon Petersson
committed
Relay selector should use overridden IP addresses for relays
1 parent 446ef2b commit 758e217

27 files changed

+429
-96
lines changed

ios/MullvadREST/ApiHandlers/ServerRelaysResponse.swift

+28
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@ extension REST {
3434
public let ipv4AddrIn: IPv4Address
3535
public let weight: UInt64
3636
public let includeInCountry: Bool
37+
38+
public func override(ipv4AddrIn: IPv4Address?) -> Self {
39+
return BridgeRelay(
40+
hostname: hostname,
41+
active: active,
42+
owned: owned,
43+
location: location,
44+
provider: provider,
45+
ipv4AddrIn: ipv4AddrIn ?? self.ipv4AddrIn,
46+
weight: weight,
47+
includeInCountry: includeInCountry
48+
)
49+
}
3750
}
3851

3952
public struct ServerRelay: Codable, Equatable {
@@ -47,6 +60,21 @@ extension REST {
4760
public let ipv6AddrIn: IPv6Address
4861
public let publicKey: Data
4962
public let includeInCountry: Bool
63+
64+
public func override(ipv4AddrIn: IPv4Address?, ipv6AddrIn: IPv6Address?) -> Self {
65+
return ServerRelay(
66+
hostname: hostname,
67+
active: active,
68+
owned: owned,
69+
location: location,
70+
provider: provider,
71+
weight: weight,
72+
ipv4AddrIn: ipv4AddrIn ?? self.ipv4AddrIn,
73+
ipv6AddrIn: ipv6AddrIn ?? self.ipv6AddrIn,
74+
publicKey: publicKey,
75+
includeInCountry: includeInCountry
76+
)
77+
}
5078
}
5179

5280
public struct ServerWireguardTunnels: Codable, Equatable {

ios/MullvadREST/Relay/AnyRelay.swift

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//
2+
// AnyRelay.swift
3+
// MullvadREST
4+
//
5+
// Created by Jon Petersson on 2024-01-31.
6+
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
7+
//
8+
9+
import MullvadTypes
10+
import Network
11+
12+
public protocol AnyRelay {
13+
var hostname: String { get }
14+
var owned: Bool { get }
15+
var location: String { get }
16+
var provider: String { get }
17+
var weight: UInt64 { get }
18+
var active: Bool { get }
19+
var includeInCountry: Bool { get }
20+
21+
func override(ipv4AddrIn: IPv4Address?, ipv6AddrIn: IPv6Address?) -> Self
22+
}
23+
24+
extension REST.ServerRelay: AnyRelay {}
25+
extension REST.BridgeRelay: AnyRelay {
26+
public func override(ipv4AddrIn: IPv4Address?, ipv6AddrIn: IPv6Address?) -> REST.BridgeRelay {
27+
override(ipv4AddrIn: ipv4AddrIn)
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//
2+
// IPOverrideWrapper.swift
3+
// MullvadREST
4+
//
5+
// Created by Jon Petersson on 2024-02-05.
6+
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
7+
//
8+
9+
import MullvadSettings
10+
import MullvadTypes
11+
12+
public class IPOverrideWrapper: RelayCacheProtocol {
13+
private let relayCache: RelayCacheProtocol
14+
private let ipOverrideRepository: any IPOverrideRepositoryProtocol
15+
16+
public init(relayCache: RelayCacheProtocol, ipOverrideRepository: any IPOverrideRepositoryProtocol) {
17+
self.relayCache = relayCache
18+
self.ipOverrideRepository = ipOverrideRepository
19+
}
20+
21+
public func read() throws -> CachedRelays {
22+
let cache = try relayCache.read()
23+
let relayResponse = apply(overrides: ipOverrideRepository.fetchAll(), to: cache.relays)
24+
25+
return CachedRelays(relays: relayResponse, updatedAt: cache.updatedAt)
26+
}
27+
28+
public func write(record: CachedRelays) throws {
29+
try relayCache.write(record: record)
30+
}
31+
32+
private func apply(
33+
overrides: [IPOverride],
34+
to relayResponse: REST.ServerRelaysResponse
35+
) -> REST.ServerRelaysResponse {
36+
let wireguard = relayResponse.wireguard
37+
let bridge = relayResponse.bridge
38+
39+
let overridenWireguardRelays = wireguard.relays.map { relay in
40+
return apply(overrides: overrides, to: relay)
41+
}
42+
let overridenBridgeRelays = bridge.relays.map { relay in
43+
return apply(overrides: overrides, to: relay)
44+
}
45+
46+
return REST.ServerRelaysResponse(
47+
locations: relayResponse.locations,
48+
wireguard: REST.ServerWireguardTunnels(
49+
ipv4Gateway: wireguard.ipv4Gateway,
50+
ipv6Gateway: wireguard.ipv6Gateway,
51+
portRanges: wireguard.portRanges,
52+
relays: overridenWireguardRelays
53+
),
54+
bridge: REST.ServerBridges(
55+
shadowsocks: bridge.shadowsocks,
56+
relays: overridenBridgeRelays
57+
)
58+
)
59+
}
60+
61+
private func apply<T: AnyRelay>(overrides: [IPOverride], to relay: T) -> T {
62+
return overrides
63+
.first { $0.hostname == relay.hostname }
64+
.flatMap {
65+
relay.override(
66+
ipv4AddrIn: $0.ipv4Address,
67+
ipv6AddrIn: $0.ipv6Address
68+
)
69+
}
70+
?? relay
71+
}
72+
}

ios/MullvadREST/Relay/RelayCache.swift

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public protocol RelayCacheProtocol {
1414
func write(record: CachedRelays) throws
1515
}
1616

17+
/// - Warning: `RelayCache` should not be used directly. It should be used through `IPOverrideWrapper` to have
18+
/// ip overrides applied.
1719
public final class RelayCache: RelayCacheProtocol {
1820
private let fileCache: any FileCacheProtocol<CachedRelays>
1921

ios/MullvadREST/Relay/RelaySelector.swift

-13
Original file line numberDiff line numberDiff line change
@@ -306,19 +306,6 @@ public struct RelaySelectorResult: Codable, Equatable {
306306
public var location: Location
307307
}
308308

309-
public protocol AnyRelay {
310-
var hostname: String { get }
311-
var owned: Bool { get }
312-
var location: String { get }
313-
var provider: String { get }
314-
var weight: UInt64 { get }
315-
var active: Bool { get }
316-
var includeInCountry: Bool { get }
317-
}
318-
319-
extension REST.ServerRelay: AnyRelay {}
320-
extension REST.BridgeRelay: AnyRelay {}
321-
322309
private struct RelayWithLocation<T: AnyRelay> {
323310
let relay: T
324311
let serverLocation: Location

ios/MullvadSettings/IPOverride.swift

+5-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ public struct RelayOverrides: Codable {
1616
}
1717
}
1818

19+
public struct IPOverrideFormatError: LocalizedError {
20+
public let errorDescription: String?
21+
}
22+
1923
public struct IPOverride: Codable, Equatable {
2024
public let hostname: String
2125
public var ipv4Address: IPv4Address?
@@ -27,7 +31,7 @@ public struct IPOverride: Codable, Equatable {
2731
case ipv6Address = "ipv6_addr_in"
2832
}
2933

30-
init(hostname: String, ipv4Address: IPv4Address?, ipv6Address: IPv6Address?) throws {
34+
public init(hostname: String, ipv4Address: IPv4Address?, ipv6Address: IPv6Address?) throws {
3135
self.hostname = hostname
3236
self.ipv4Address = ipv4Address
3337
self.ipv6Address = ipv6Address
@@ -49,7 +53,3 @@ public struct IPOverride: Codable, Equatable {
4953
}
5054
}
5155
}
52-
53-
public struct IPOverrideFormatError: LocalizedError {
54-
public let errorDescription: String?
55-
}

ios/MullvadSettings/IPOverrideRepository.swift

+12-11
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ import MullvadLogging
1212
public protocol IPOverrideRepositoryProtocol {
1313
func add(_ overrides: [IPOverride])
1414
func fetchAll() -> [IPOverride]
15-
func fetchByHostname(_ hostname: String) -> IPOverride?
1615
func deleteAll()
1716
func parse(data: Data) throws -> [IPOverride]
1817
}
1918

2019
public class IPOverrideRepository: IPOverrideRepositoryProtocol {
2120
private let logger = Logger(label: "IPOverrideRepository")
21+
private let readWriteLock = NSLock()
2222

2323
public init() {}
2424

@@ -54,13 +54,11 @@ public class IPOverrideRepository: IPOverrideRepositoryProtocol {
5454
return (try? readIpOverrides()) ?? []
5555
}
5656

57-
public func fetchByHostname(_ hostname: String) -> IPOverride? {
58-
return fetchAll().first { $0.hostname == hostname }
59-
}
60-
6157
public func deleteAll() {
6258
do {
63-
try SettingsManager.store.delete(key: .ipOverrides)
59+
try readWriteLock.withLock {
60+
try SettingsManager.store.delete(key: .ipOverrides)
61+
}
6462
} catch {
6563
logger.error("Could not delete all overrides. \nError: \(error)")
6664
}
@@ -74,17 +72,20 @@ public class IPOverrideRepository: IPOverrideRepositoryProtocol {
7472
}
7573

7674
private func readIpOverrides() throws -> [IPOverride] {
77-
let parser = makeParser()
78-
let data = try SettingsManager.store.read(key: .ipOverrides)
79-
80-
return try parser.parseUnversionedPayload(as: [IPOverride].self, from: data)
75+
try readWriteLock.withLock {
76+
let parser = makeParser()
77+
let data = try SettingsManager.store.read(key: .ipOverrides)
78+
return try parser.parseUnversionedPayload(as: [IPOverride].self, from: data)
79+
}
8180
}
8281

8382
private func writeIpOverrides(_ overrides: [IPOverride]) throws {
8483
let parser = makeParser()
8584
let data = try parser.produceUnversionedPayload(overrides)
8685

87-
try SettingsManager.store.write(data, for: .ipOverrides)
86+
try readWriteLock.withLock {
87+
try SettingsManager.store.write(data, for: .ipOverrides)
88+
}
8889
}
8990

9091
private func makeParser() -> SettingsParser {

ios/MullvadVPN.xcodeproj/project.pbxproj

+16
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,8 @@
486486
7A3FD1B82AD54AE60042BEA6 /* TimeServerProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BDEB9A2A98F58600F578F2 /* TimeServerProxy.swift */; };
487487
7A42DEC92A05164100B209BE /* SettingsInputCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A42DEC82A05164100B209BE /* SettingsInputCell.swift */; };
488488
7A516C2E2B6D357500BBD33D /* URL+Scoping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A516C2D2B6D357500BBD33D /* URL+Scoping.swift */; };
489+
7A516C3A2B7111A700BBD33D /* IPOverrideWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A516C392B7111A700BBD33D /* IPOverrideWrapper.swift */; };
490+
7A516C3C2B712F0B00BBD33D /* IPOverrideWrapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A516C3B2B712F0B00BBD33D /* IPOverrideWrapperTests.swift */; };
489491
7A5869952B32E9C700640D27 /* LinkButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A5869942B32E9C700640D27 /* LinkButton.swift */; };
490492
7A5869972B32EA4500640D27 /* AppButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A5869962B32EA4500640D27 /* AppButton.swift */; };
491493
7A58699B2B482FE200640D27 /* UITableViewCell+Disable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A58699A2B482FE200640D27 /* UITableViewCell+Disable.swift */; };
@@ -560,6 +562,8 @@
560562
7AD0AA1D2AD6A86700119E10 /* PacketTunnelActorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AD0AA192AD69B6E00119E10 /* PacketTunnelActorProtocol.swift */; };
561563
7AD0AA1F2AD6C8B900119E10 /* URLRequestProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AD0AA1E2AD6C8B900119E10 /* URLRequestProxyProtocol.swift */; };
562564
7AD0AA212AD6CB0000119E10 /* URLRequestProxyStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AD0AA202AD6CB0000119E10 /* URLRequestProxyStub.swift */; };
565+
7ADCB2D82B6A6EB300C88F89 /* AnyRelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADCB2D72B6A6EB300C88F89 /* AnyRelay.swift */; };
566+
7ADCB2DA2B6A730400C88F89 /* IPOverrideRepositoryStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADCB2D92B6A730400C88F89 /* IPOverrideRepositoryStub.swift */; };
563567
7AE044BB2A935726003915D8 /* Routing.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A88DCD02A8FABBE00D2FF0E /* Routing.h */; settings = {ATTRIBUTES = (Public, ); }; };
564568
7AEF7F1A2AD00F52006FE45D /* AppMessageHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AEF7F192AD00F52006FE45D /* AppMessageHandler.swift */; };
565569
7AF10EB22ADE859200C090B9 /* AlertViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF10EB12ADE859200C090B9 /* AlertViewController.swift */; };
@@ -1666,6 +1670,8 @@
16661670
7A3FD1B42AD4465A0042BEA6 /* AppMessageHandlerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppMessageHandlerTests.swift; sourceTree = "<group>"; };
16671671
7A42DEC82A05164100B209BE /* SettingsInputCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsInputCell.swift; sourceTree = "<group>"; };
16681672
7A516C2D2B6D357500BBD33D /* URL+Scoping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Scoping.swift"; sourceTree = "<group>"; };
1673+
7A516C392B7111A700BBD33D /* IPOverrideWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPOverrideWrapper.swift; sourceTree = "<group>"; };
1674+
7A516C3B2B712F0B00BBD33D /* IPOverrideWrapperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPOverrideWrapperTests.swift; sourceTree = "<group>"; };
16691675
7A5869942B32E9C700640D27 /* LinkButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkButton.swift; sourceTree = "<group>"; };
16701676
7A5869962B32EA4500640D27 /* AppButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppButton.swift; sourceTree = "<group>"; };
16711677
7A58699A2B482FE200640D27 /* UITableViewCell+Disable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableViewCell+Disable.swift"; sourceTree = "<group>"; };
@@ -1732,6 +1738,8 @@
17321738
7AD0AA1B2AD6A63F00119E10 /* PacketTunnelActorStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelActorStub.swift; sourceTree = "<group>"; };
17331739
7AD0AA1E2AD6C8B900119E10 /* URLRequestProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLRequestProxyProtocol.swift; sourceTree = "<group>"; };
17341740
7AD0AA202AD6CB0000119E10 /* URLRequestProxyStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLRequestProxyStub.swift; sourceTree = "<group>"; };
1741+
7ADCB2D72B6A6EB300C88F89 /* AnyRelay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyRelay.swift; sourceTree = "<group>"; };
1742+
7ADCB2D92B6A730400C88F89 /* IPOverrideRepositoryStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPOverrideRepositoryStub.swift; sourceTree = "<group>"; };
17351743
7AEF7F192AD00F52006FE45D /* AppMessageHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppMessageHandler.swift; sourceTree = "<group>"; };
17361744
7AF10EB12ADE859200C090B9 /* AlertViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertViewController.swift; sourceTree = "<group>"; };
17371745
7AF10EB32ADE85BC00C090B9 /* RelayFilterCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RelayFilterCoordinator.swift; sourceTree = "<group>"; };
@@ -2745,8 +2753,10 @@
27452753
58B0A2A4238EE67E00BC001D /* Info.plist */,
27462754
A9B6AC192ADE8FBB00F7802A /* InMemorySettingsStore.swift */,
27472755
F07BF2572A26112D00042943 /* InputTextFormatterTests.swift */,
2756+
7ADCB2D92B6A730400C88F89 /* IPOverrideRepositoryStub.swift */,
27482757
7A5869C22B5820CE00640D27 /* IPOverrideRepositoryTests.swift */,
27492758
7AB4CCB82B69097E006037F5 /* IPOverrideTests.swift */,
2759+
7A516C3B2B712F0B00BBD33D /* IPOverrideWrapperTests.swift */,
27502760
A9B6AC172ADE8F4300F7802A /* MigrationManagerTests.swift */,
27512761
58C3FA652A38549D006A450A /* MockFileCache.swift */,
27522762
F09D04B42AE93CB6003D4F89 /* OutgoingConnectionProxy+Stub.swift */,
@@ -3461,8 +3471,10 @@
34613471
F0DC779F2B2222D20087F09D /* Relay */ = {
34623472
isa = PBXGroup;
34633473
children = (
3474+
7ADCB2D72B6A6EB300C88F89 /* AnyRelay.swift */,
34643475
585DA87626B024A600B8C587 /* CachedRelays.swift */,
34653476
F0DDE4272B220A15006B57A7 /* Haversine.swift */,
3477+
7A516C392B7111A700BBD33D /* IPOverrideWrapper.swift */,
34663478
F0DDE4292B220A15006B57A7 /* Midpoint.swift */,
34673479
5820675A26E6576800655B05 /* RelayCache.swift */,
34683480
F0DDE4282B220A15006B57A7 /* RelaySelector.swift */,
@@ -4438,6 +4450,7 @@
44384450
06799AF228F98E4800ACD94E /* RESTAccessTokenManager.swift in Sources */,
44394451
A90763B12B2857D50045ADF0 /* Socks5Endpoint.swift in Sources */,
44404452
06799AF328F98E4800ACD94E /* RESTAuthenticationProxy.swift in Sources */,
4453+
7A516C3A2B7111A700BBD33D /* IPOverrideWrapper.swift in Sources */,
44414454
F0DDE4142B220458006B57A7 /* ShadowSocksProxy.swift in Sources */,
44424455
A90763B62B2857D50045ADF0 /* Socks5ConnectNegotiation.swift in Sources */,
44434456
F06045E62B231EB700B2D37A /* URLSessionTransport.swift in Sources */,
@@ -4459,6 +4472,7 @@
44594472
A90763B42B2857D50045ADF0 /* NWConnection+Extensions.swift in Sources */,
44604473
F06045EA2B23217E00B2D37A /* ShadowsocksTransport.swift in Sources */,
44614474
06799AFC28F98EE300ACD94E /* AddressCache.swift in Sources */,
4475+
7ADCB2D82B6A6EB300C88F89 /* AnyRelay.swift in Sources */,
44624476
06799AF028F98E4800ACD94E /* REST.swift in Sources */,
44634477
06799ADF28F98E4800ACD94E /* RESTDevicesProxy.swift in Sources */,
44644478
06799ADA28F98E4800ACD94E /* RESTResponseHandler.swift in Sources */,
@@ -4574,6 +4588,7 @@
45744588
7A6F2FA52AFA3CB2006D0856 /* AccountExpiryTests.swift in Sources */,
45754589
A9A5FA082ACB05160083449F /* StorePaymentBlockObserver.swift in Sources */,
45764590
A9E0317C2ACBFC7E0095D843 /* TunnelStore+Stubs.swift in Sources */,
4591+
7A516C3C2B712F0B00BBD33D /* IPOverrideWrapperTests.swift in Sources */,
45774592
A9A5FA092ACB05160083449F /* SendStoreReceiptOperation.swift in Sources */,
45784593
A9A5FA0A2ACB05160083449F /* StorePaymentEvent.swift in Sources */,
45794594
A9A5FA0B2ACB05160083449F /* StorePaymentManager.swift in Sources */,
@@ -4624,6 +4639,7 @@
46244639
A9A5FA2F2ACB05160083449F /* FixedWidthIntegerArithmeticsTests.swift in Sources */,
46254640
A9A5FA302ACB05160083449F /* InputTextFormatterTests.swift in Sources */,
46264641
F0B0E6972AFE6E7E001DC66B /* XCTest+Async.swift in Sources */,
4642+
7ADCB2DA2B6A730400C88F89 /* IPOverrideRepositoryStub.swift in Sources */,
46274643
A9A5FA312ACB05160083449F /* MockFileCache.swift in Sources */,
46284644
A9A5FA322ACB05160083449F /* RelayCacheTests.swift in Sources */,
46294645
A9A5FA332ACB05160083449F /* RelaySelectorTests.swift in Sources */,

ios/MullvadVPN/AppDelegate.swift

+12-3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
4545
private(set) var accessMethodRepository = AccessMethodRepository()
4646
private(set) var shadowsocksLoader: ShadowsocksLoaderProtocol!
4747
private(set) var configuredTransportProvider: ProxyConfigurationTransportProvider!
48+
private(set) var ipOverrideRepository = IPOverrideRepository()
4849

4950
// MARK: - Application lifecycle
5051

@@ -66,8 +67,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
6667

6768
setUpProxies(containerURL: containerURL)
6869

69-
let relayCache = RelayCache(cacheDirectory: containerURL)
70-
relayCacheTracker = RelayCacheTracker(relayCache: relayCache, application: application, apiProxy: apiProxy)
70+
let ipOverrideWrapper = IPOverrideWrapper(
71+
relayCache: RelayCache(cacheDirectory: containerURL),
72+
ipOverrideRepository: ipOverrideRepository
73+
)
74+
75+
relayCacheTracker = RelayCacheTracker(
76+
relayCache: ipOverrideWrapper,
77+
application: application,
78+
apiProxy: apiProxy
79+
)
7180

7281
addressCacheTracker = AddressCacheTracker(application: application, apiProxy: apiProxy, store: addressCache)
7382

@@ -93,7 +102,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
93102

94103
shadowsocksLoader = ShadowsocksLoader(
95104
shadowsocksCache: shadowsocksCache,
96-
relayCache: relayCache,
105+
relayCache: ipOverrideWrapper,
97106
constraintsUpdater: constraintsUpdater
98107
)
99108

0 commit comments

Comments
 (0)