Skip to content

Commit

Permalink
Add concrete IPv4 and IPv6 types (#21)
Browse files Browse the repository at this point in the history
Motivation:

The `ARecord` and `AAAARecord` use the `IPAddress` `enum` as their
address types. However, they should only use IPv4 and IPv6 addresses
respectively.

Modifications:

- Add `IPAddress.IPv4` and IPAddress.IPv6` types and use them as the
  associated values in the `IPAddress` enum
- Change the casing of the `IPAddress` cases from `.IPv4` and `.IPv6` to
  `.ipv4` and `.ipv6` as Swift case names are usually lower-camel case

Result:

- The types of IP address used by `ARecord` and `AAAARecord` are clearer
  • Loading branch information
glbrntt authored Feb 14, 2024
1 parent 62fbedd commit 96a18c6
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 16 deletions.
34 changes: 26 additions & 8 deletions Sources/AsyncDNSResolver/AsyncDNSResolver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -185,21 +185,39 @@ enum QueryType {
// MARK: - Query reply types

public enum IPAddress: Sendable, Equatable, CustomStringConvertible {
case IPv4(String)
case IPv6(String)
case ipv4(IPv4)
case ipv6(IPv6)

public var description: String {
switch self {
case .IPv4(let address):
return address
case .IPv6(let address):
return address
case .ipv4(let address):
return String(describing: address)
case .ipv6(let address):
return String(describing: address)
}
}

public struct IPv4: Sendable, Hashable, CustomStringConvertible {
public var address: String
public var description: String { self.address }

public init(address: String) {
self.address = address
}
}

public struct IPv6: Sendable, Hashable, CustomStringConvertible {
public var address: String
public var description: String { self.address }

public init(address: String) {
self.address = address
}
}
}

public struct ARecord: Sendable, Equatable, CustomStringConvertible {
public let address: IPAddress
public let address: IPAddress.IPv4
public let ttl: Int32?

public var description: String {
Expand All @@ -208,7 +226,7 @@ public struct ARecord: Sendable, Equatable, CustomStringConvertible {
}

public struct AAAARecord: Sendable, Equatable, CustomStringConvertible {
public let address: IPAddress
public let address: IPAddress.IPv6
public let ttl: Int32?

public var description: String {
Expand Down
12 changes: 7 additions & 5 deletions Sources/AsyncDNSResolver/c-ares/DNSResolver_c-ares.swift
Original file line number Diff line number Diff line change
Expand Up @@ -579,32 +579,34 @@ private func toStringArray(_ arrayPointer: UnsafeMutablePointer<UnsafeMutablePoi
return result
}

extension IPAddress {
extension IPAddress.IPv4 {
init(_ address: in_addr) {
var address = address
var addressBytes = [CChar](repeating: 0, count: Int(INET_ADDRSTRLEN))
inet_ntop(AF_INET, &address, &addressBytes, socklen_t(INET_ADDRSTRLEN))
self = .IPv4(String(cString: addressBytes))
self = .init(address: String(cString: addressBytes))
}
}

extension IPAddress.IPv6 {
init(_ address: ares_in6_addr) {
var address = address
var addressBytes = [CChar](repeating: 0, count: Int(INET6_ADDRSTRLEN))
inet_ntop(AF_INET6, &address, &addressBytes, socklen_t(INET6_ADDRSTRLEN))
self = .IPv6(String(cString: addressBytes))
self = .init(address: String(cString: addressBytes))
}
}

extension ARecord {
init(_ addrttl: ares_addrttl) {
self.address = IPAddress(addrttl.ipaddr)
self.address = IPAddress.IPv4(addrttl.ipaddr)
self.ttl = addrttl.ttl
}
}

extension AAAARecord {
init(_ addrttl: ares_addr6ttl) {
self.address = IPAddress(addrttl.ip6addr)
self.address = IPAddress.IPv6(addrttl.ip6addr)
self.ttl = addrttl.ttl
}
}
4 changes: 2 additions & 2 deletions Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ extension DNSSD {
var parsedAddressBytes = [CChar](repeating: 0, count: Int(INET_ADDRSTRLEN))
inet_ntop(AF_INET, ptr, &parsedAddressBytes, socklen_t(INET_ADDRSTRLEN))
let parsedAddress = String(cString: parsedAddressBytes)
return ARecord(address: .IPv4(parsedAddress), ttl: nil)
return ARecord(address: .init(address: parsedAddress), ttl: nil)
}

func generateReply(records: [ARecord]) throws -> [ARecord] {
Expand All @@ -253,7 +253,7 @@ extension DNSSD {
var parsedAddressBytes = [CChar](repeating: 0, count: Int(INET6_ADDRSTRLEN))
inet_ntop(AF_INET6, ptr, &parsedAddressBytes, socklen_t(INET6_ADDRSTRLEN))
let parsedAddress = String(cString: parsedAddressBytes)
return AAAARecord(address: .IPv6(parsedAddress), ttl: nil)
return AAAARecord(address: .init(address: parsedAddress), ttl: nil)
}

func generateReply(records: [AAAARecord]) throws -> [AAAARecord] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ final class DNSSDDNSResolverTests: XCTestCase {
let addrBytes: [UInt8] = [38, 32, 1, 73]
try addrBytes.withUnsafeBufferPointer {
let record = try DNSSD.AQueryReplyHandler.instance.parseRecord(data: $0.baseAddress, length: UInt16($0.count))
XCTAssertEqual(record, ARecord(address: .IPv4("38.32.1.73"), ttl: nil))
XCTAssertEqual(record, ARecord(address: .init(address: "38.32.1.73"), ttl: nil))
}
}

Expand Down

0 comments on commit 96a18c6

Please sign in to comment.