From 62997d6091c793ad50aa68845eae2c68323d4ab2 Mon Sep 17 00:00:00 2001 From: Martin Fitzka-Reichart Date: Mon, 27 Sep 2021 11:29:56 +0200 Subject: [PATCH] Add IPv4 preference support Adds an option to prefer IPv4 addresses for querying if both IPv4 and IPv6 addresses are resolved. Signed-off-by: Martin Fitzka-Reichart --- Sources/Clock.swift | 4 +++- Sources/NTPClient.swift | 12 +++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Sources/Clock.swift b/Sources/Clock.swift index fade988..afc5a7b 100644 --- a/Sources/Clock.swift +++ b/Sources/Clock.swift @@ -63,15 +63,17 @@ public struct Clock { /// - parameter pool: NTP pool that will be resolved into multiple NTP servers that will be used for /// the synchronization. /// - parameter samples: The number of samples to be acquired from each server (default 4). + /// - parameter preferIPv4: Prefer IPv4 addresses to query if both IPv4 and IPv6 addresses are returned. /// - parameter completion: A closure that will be called after _all_ the NTP calls are finished. /// - parameter first: A closure that will be called after the first valid date is calculated. public static func sync(from pool: String = "time.apple.com", samples: Int = 4, + preferIPv4: Bool = false, first: ((Date, TimeInterval) -> Void)? = nil, completion: ((Date?, TimeInterval?) -> Void)? = nil) { self.loadFromDefaults() - NTPClient().query(pool: pool, numberOfSamples: samples) { offset, done, total in + NTPClient().query(pool: pool, numberOfSamples: samples, preferIPv4: preferIPv4) { offset, done, total in if let offset = offset { self.stableTime = TimeFreeze(offset: offset) diff --git a/Sources/NTPClient.swift b/Sources/NTPClient.swift index 322146e..4a71f5b 100644 --- a/Sources/NTPClient.swift +++ b/Sources/NTPClient.swift @@ -21,11 +21,13 @@ final class NTPClient { /// - parameter port: Server NTP port (default 123). /// - parameter version: NTP version to use (default 3). /// - parameter numberOfSamples: The number of samples to be acquired from each server (default 4). + /// - parameter preferIPv4: Prefer IPv4 addresses to query if both IPv4 and IPv6 addresses are returned. /// - parameter maximumServers: The maximum number of servers to be queried (default 5). /// - parameter timeout: The individual timeout for each of the NTP operations. /// - parameter completion: A closure that will be response PDU on success or nil on error. func query(pool: String = "time.apple.com", version: Int8 = 3, port: Int = 123, - numberOfSamples: Int = kDefaultSamples, maximumServers: Int = kMaximumNTPServers, + numberOfSamples: Int = kDefaultSamples, preferIPv4: Bool = false, + maximumServers: Int = kMaximumNTPServers, timeout: CFTimeInterval = kDefaultTimeout, progress: @escaping (TimeInterval?, Int, Int) -> Void) { @@ -59,9 +61,13 @@ final class NTPClient { if addresses.count == 0 { return progress(nil, 0, 0) } + + let addressesToQuery = preferIPv4 && !addresses.filter({ $0.family == PF_INET }).isEmpty + ? addresses.filter({ $0.family == PF_INET }) + : addresses - let totalServers = min(addresses.count, maximumServers) - for address in addresses[0 ..< totalServers] { + let totalServers = min(addressesToQuery.count, maximumServers) + for address in addressesToQuery[0 ..< totalServers] { queryIPAndStoreResult(address, totalServers * numberOfSamples) } }