From e2d6c13ed00b750fb3b4e26eff68a9361631ceae Mon Sep 17 00:00:00 2001 From: Nikolay Edigaryev Date: Fri, 23 Feb 2024 16:49:06 +0400 Subject: [PATCH] DHCP MAC-address resolver: handle duplicate leases (#740) --- Sources/tart/MACAddressResolver/Leases.swift | 5 ++++- Tests/TartTests/LeasesTests.swift | 23 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Sources/tart/MACAddressResolver/Leases.swift b/Sources/tart/MACAddressResolver/Leases.swift index 7a2f5f8..184543c 100644 --- a/Sources/tart/MACAddressResolver/Leases.swift +++ b/Sources/tart/MACAddressResolver/Leases.swift @@ -45,7 +45,10 @@ class Leases { (lease.mac, lease) }) - self.leases = Dictionary(uniqueKeysWithValues: leases) + self.leases = Dictionary(leases) { (left, right) in + // When duplicate lease is found, prefer a newer lease over the older one + (left.expiresAt > right.expiresAt) ? left : right + } } /// Parse leases from the host cache similarly to the PLCache_read() function found in Apple's Open Source releases. diff --git a/Tests/TartTests/LeasesTests.swift b/Tests/TartTests/LeasesTests.swift index e08824f..8982c75 100644 --- a/Tests/TartTests/LeasesTests.swift +++ b/Tests/TartTests/LeasesTests.swift @@ -35,4 +35,27 @@ final class LeasesTests: XCTestCase { XCTAssertEqual(IPv4Address("1.2.3.4"), leases.ResolveMACAddress(macAddress: macAddress)) } + + func testDuplicateYetNotExpiredLeases() throws { + let macAddress = MACAddress(fromString: "11:22:33:44:55:66")! + + let leases = try Leases(""" + { + name=debian + ip_address=192.168.64.1 + hw_address=1,\(macAddress) + identifier=1,\(macAddress) + lease=\(Int((Date() + 10.minutes).timeIntervalSince1970).hex) + } + { + name=debian + ip_address=192.168.64.2 + hw_address=1,\(macAddress) + identifier=1,\(macAddress) + lease=\(Int((Date() + 5.minutes).timeIntervalSince1970).hex) + } + """) + + XCTAssertEqual(IPv4Address("192.168.64.1"), leases.ResolveMACAddress(macAddress: macAddress)) + } }