Improve onion request path loading efficiency
This commit is contained in:
parent
5524ab1932
commit
be877bbeaf
|
@ -305,6 +305,7 @@
|
|||
B8FF8DAF25C0D00F004D1F22 /* SessionUtilitiesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C2A679255388CC00C340D1 /* SessionUtilitiesKit.framework */; };
|
||||
B8FF8E6225C10DA5004D1F22 /* GeoLite2-Country-Blocks-IPv4 in Resources */ = {isa = PBXBuildFile; fileRef = B8FF8E6125C10DA5004D1F22 /* GeoLite2-Country-Blocks-IPv4 */; };
|
||||
B8FF8E7425C10FC3004D1F22 /* GeoLite2-Country-Locations-English in Resources */ = {isa = PBXBuildFile; fileRef = B8FF8E7325C10FC3004D1F22 /* GeoLite2-Country-Locations-English */; };
|
||||
B8FF8EA625C11FEF004D1F22 /* IPv4.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8FF8EA525C11FEF004D1F22 /* IPv4.swift */; };
|
||||
B90418E6183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; };
|
||||
B9EB5ABD1884C002007CBB57 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9EB5ABC1884C002007CBB57 /* MessageUI.framework */; };
|
||||
C300A5B22554AF9800555489 /* VisibleMessage+Profile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5B12554AF9800555489 /* VisibleMessage+Profile.swift */; };
|
||||
|
@ -1347,6 +1348,7 @@
|
|||
B8D8F1EF256621180092EF10 /* MessageSender+Convenience.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "MessageSender+Convenience.swift"; path = "../../SignalUtilitiesKit/Messaging/Sending & Receiving/MessageSender+Convenience.swift"; sourceTree = "<group>"; };
|
||||
B8FF8E6125C10DA5004D1F22 /* GeoLite2-Country-Blocks-IPv4 */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; name = "GeoLite2-Country-Blocks-IPv4"; path = "Countries/GeoLite2-Country-Blocks-IPv4"; sourceTree = "<group>"; };
|
||||
B8FF8E7325C10FC3004D1F22 /* GeoLite2-Country-Locations-English */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; name = "GeoLite2-Country-Locations-English"; path = "Countries/GeoLite2-Country-Locations-English"; sourceTree = "<group>"; };
|
||||
B8FF8EA525C11FEF004D1F22 /* IPv4.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPv4.swift; sourceTree = "<group>"; };
|
||||
B90418E4183E9DD40038554A /* DateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateUtil.h; sourceTree = "<group>"; };
|
||||
B90418E5183E9DD40038554A /* DateUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DateUtil.m; sourceTree = "<group>"; };
|
||||
B9EB5ABC1884C002007CBB57 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; };
|
||||
|
@ -2264,6 +2266,7 @@
|
|||
children = (
|
||||
C33FDB68255A580F00E217F9 /* ContentProxy.swift */,
|
||||
C3C2A5BC255385EE00C340D1 /* HTTP.swift */,
|
||||
B8FF8EA525C11FEF004D1F22 /* IPv4.swift */,
|
||||
C3C2A5D92553860B00C340D1 /* JSON.swift */,
|
||||
C33FDAF2255A580500E217F9 /* ProxiedContentDownloader.swift */,
|
||||
C352A3A42557B5F000338F3E /* TSRequest.h */,
|
||||
|
@ -4838,6 +4841,7 @@
|
|||
B8856D23256F116B001CE70E /* Weak.swift in Sources */,
|
||||
C32C5A48256DB8F0003C73A2 /* BuildConfiguration.swift in Sources */,
|
||||
C300A60D2554B31900555489 /* Logging.swift in Sources */,
|
||||
B8FF8EA625C11FEF004D1F22 /* IPv4.swift in Sources */,
|
||||
C3D9E35525675EE10040E4F3 /* MIMETypeUtil.m in Sources */,
|
||||
C3A7219A2558C1660043A11F /* AnyPromise+Conversion.swift in Sources */,
|
||||
C300A6322554B6D100555489 /* NSDate+Timestamp.mm in Sources */,
|
||||
|
|
Binary file not shown.
|
@ -2,10 +2,18 @@
|
|||
final class IP2Country {
|
||||
var countryNamesCache: [String:String] = [:]
|
||||
|
||||
private lazy var ipv4Table: [String:[String]] = {
|
||||
private static let workQueue = DispatchQueue(label: "IP2Country.workQueue", qos: .utility) // It's important that this is a serial queue
|
||||
static var isInitialized = false
|
||||
|
||||
// MARK: Tables
|
||||
/// This table has two columns: the "network" column and the "registered_country_geoname_id" column. The network column contains the **lower** bound of an IP
|
||||
/// range and the "registered_country_geoname_id" column contains the ID of the country corresponding to that range. We look up an IP by finding the first index in the
|
||||
/// network column where the value is greater than the IP we're looking up (converted to an integer). The IP we're looking up must then be in the range **before** that
|
||||
/// range.
|
||||
private lazy var ipv4Table: [String:[Int]] = {
|
||||
let url = Bundle.main.url(forResource: "GeoLite2-Country-Blocks-IPv4", withExtension: nil)!
|
||||
let data = try! Data(contentsOf: url)
|
||||
return try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! [String:[String]]
|
||||
return try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! [String:[Int]]
|
||||
}()
|
||||
|
||||
private lazy var countryNamesTable: [String:[String]] = {
|
||||
|
@ -14,10 +22,6 @@ final class IP2Country {
|
|||
return try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! [String:[String]]
|
||||
}()
|
||||
|
||||
private static let workQueue = DispatchQueue(label: "IP2Country.workQueue", qos: .utility) // It's important that this is a serial queue
|
||||
|
||||
static var isInitialized = false
|
||||
|
||||
// MARK: Lifecycle
|
||||
static let shared = IP2Country()
|
||||
|
||||
|
@ -28,29 +32,17 @@ final class IP2Country {
|
|||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Implementation
|
||||
private func cacheCountry(for ip: String) -> String {
|
||||
var truncatedIP = ip
|
||||
func getCountryInternal() -> String {
|
||||
if let country = countryNamesCache[ip] { return country }
|
||||
if let ipv4TableIndex = ipv4Table["network"]!.firstIndex(where: { $0.starts(with: truncatedIP) }) {
|
||||
let countryID = ipv4Table["registered_country_geoname_id"]![ipv4TableIndex]
|
||||
if let countryNamesTableIndex = countryNamesTable["geoname_id"]!.firstIndex(of: countryID) {
|
||||
let country = countryNamesTable["country_name"]![countryNamesTableIndex]
|
||||
countryNamesCache[ip] = country
|
||||
return country
|
||||
}
|
||||
}
|
||||
if truncatedIP.contains(".") && !truncatedIP.hasSuffix(".") { // The fuzziest we want to go is xxx.x
|
||||
truncatedIP.removeLast()
|
||||
if truncatedIP.hasSuffix(".") { truncatedIP.removeLast() }
|
||||
return getCountryInternal()
|
||||
} else {
|
||||
return "Unknown Country"
|
||||
}
|
||||
}
|
||||
return getCountryInternal()
|
||||
if let result = countryNamesCache[ip] { return result }
|
||||
let ipAsInt = IPv4.toInt(ip)
|
||||
guard let ipv4TableIndex = given(ipv4Table["network"]!.firstIndex(where: { $0 > ipAsInt }), { $0 - 1 }) else { return "Unknown Country" } // Relies on the array being sorted
|
||||
let countryID = ipv4Table["registered_country_geoname_id"]![ipv4TableIndex]
|
||||
guard let countryNamesTableIndex = countryNamesTable["geoname_id"]!.firstIndex(of: String(countryID)) else { return "Unknown Country" }
|
||||
let result = countryNamesTable["country_name"]![countryNamesTableIndex]
|
||||
countryNamesCache[ip] = result
|
||||
return result
|
||||
}
|
||||
|
||||
@objc func populateCacheIfNeededAsync() {
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
public enum IPv4 {
|
||||
|
||||
public static func toInt(_ ip: String) -> Int {
|
||||
let octets: [Int] = ip.split(separator: ".").map { Int($0)! }
|
||||
var result: Int = 0
|
||||
for i in stride(from: 3, through: 0, by: -1) {
|
||||
result += octets[ 3 - i ] << (i * 8)
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue