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)) + } }