summaryrefslogtreecommitdiffhomepage
path: root/ios/MullvadVPN/RelayList.swift
blob: 190432e8053f52e7447a71e66e5bd9ba01a8315f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//
//  RelayList.swift
//  MullvadVPN
//
//  Created by pronebird on 02/05/2019.
//  Copyright © 2019 Mullvad VPN AB. All rights reserved.
//

import Foundation
import Network

struct RelayList: Codable {
    struct Country: Codable {
        var name: String
        var code: String
        var cities: [City]
    }

    struct City: Codable {
        var name: String
        var code: String
        var latitude: Double
        var longitude: Double
        var relays: [Hostname]
    }

    struct Hostname: Codable {
        var hostname: String
        var ipv4AddrIn: IPv4Address
        var includeInCountry: Bool
        var active: Bool
        var weight: Int32
        var tunnels: Tunnels?
    }

    struct Tunnels: Codable {
        var wireguard: [WireguardTunnel]?
    }

    struct WireguardTunnel: Codable {
        var ipv4Gateway: IPv4Address
        var ipv6Gateway: IPv6Address
        var publicKey: Data
        var portRanges: [ClosedRange<UInt16>]
    }

    var countries: [Country]
}

extension RelayList {

    /// Returns an alphabetically sorted `RelayList`
    func sorted() -> Self {
        let lexicalComparator = { (a: String, b: String) -> Bool in
            return a.localizedCaseInsensitiveCompare(b) == .orderedAscending
        }

        let fileComparator = { (a: String, b: String) -> Bool in
            return a.localizedStandardCompare(b) == .orderedAscending
        }

        let sortedCountries = countries
            .sorted { lexicalComparator($0.name, $1.name) }
            .map { (country) -> RelayList.Country in
                var sortedCountry = country
                sortedCountry.cities = country.cities.sorted { lexicalComparator($0.name, $1.name) }
                    .map({ (city) -> RelayList.City in
                        var sortedCity = city
                        sortedCity.relays = city.relays
                            .sorted { fileComparator($0.hostname, $1.hostname) }
                        return sortedCity
                    })
                return sortedCountry
        }

        return RelayList(countries: sortedCountries)
    }

}