swift-dns

main

A high-performance Swift DNS library built on top of SwiftNIO; aiming to provide DNS client, resolver and server implementations.
swift-dns/swift-dns

Unit Tests CI Integration Tests CI Benchamrks CI Swift 6.2.3+

swift-dns

A high-performance Swift DNS library built on top of SwiftNIO; aiming to provide DNS client, resolver and server implementations.

Usage

Initialize a ForwardingDNSResolver, then use the query methods:

import DNSClient
import DNSModels

/// Create a `ForwardingDNSResolver`
let resolver = try ForwardingDNSResolver(
    transport: .default(
        serverAddress: .domain(
            /// Connect to Cloudflare's DNS primary server @ 1.1.1.1
            domainName: DomainName(ipv4: IPv4Address(1, 1, 1, 1)),
            port: 53
        )
    )
)

try await withThrowingTaskGroup(of: Void.self) { taskGroup in
    /// Use `addImmediateTask` instead of `addTask` on macOS 26 or Linux.
    taskGroup.addTask {
        try await resolver.run()/// !important
    }

    /// You can use the resolver while the `resolver.run()` method is not cancelled.

    /// Send the query
    /// `response` will be of type `Message`
    let response = try await resolver.queryA(
        message: .forQuery(domainName: "mahdibm.com")
    )

    /// Read the answers
    for answer in response.answers {
        /// `a` will be of type `A`
        let a = answer.rdata
        /// `ipv4` will be of type `IPv4Address`
        let ipv4 = a.value
        print(
            "Got ipv4 \(ipv4) for domain \(response.queries.first?.domainName.description ?? "n/a")"
        )
    }

    /// To shutdown the resolver, cancel its run method, by cancelling the taskGroup.
    taskGroup.cancelAll()
}

You can use different transports if you so desire. The default transport is preferUDPOrUseTCP similar to other DNS resolvers and resolvers. Currently a TCP-only transport is also supported:

/// Create a `ForwardingDNSResolver` with the TCP transport
let resolver = try ForwardingDNSResolver(
    transport: .tcp(
        serverAddress: .domain(
            domainName: DomainName(ipv4: IPv4Address(1, 1, 1, 1)),
            port: 53
        )
    )
)

Operators

I'm experimenting with using operators that do checks in debug builds, but are unchecked in optimized builds.

These operators always have 2 of the last character of the normal operator, and they should in theory always result in the same value as their stdlib version.

Some examples of these operators are:

  • &+ -> &++
  • &+= -> &+==
  • &>> -> &>>>

Checklist

  • DNS Parsing
    • IDNA support for non-ASCII domain names.
  • DNS client
    • DNS over UDP
    • DNS over TCP
    • DoT (DNS Over TLS)
    • DoH (DNS Over HTTPS)
    • DoQ (DNS Over Quic)
    • MDNS
  • DNS resolver
    • ForwardingDNSResolver: A DNS client but with caching.
    • _RecursiveDNSResolver: Implementation is in progress
  • DNS server
  • DNSSEC

Credits

Description

  • Swift Tools 6.2.1
View More Packages from this Author

Dependencies

Last updated: Thu Apr 09 2026 01:11:53 GMT-0900 (Hawaii-Aleutian Daylight Time)