https://github.com/swift-dns/swift-dns
A high-performance Swift DNS library built on top of SwiftNIO; aiming to provide DNS client, resolver and server implementations.
https://github.com/swift-dns/swift-dns
client dns server swift
Last synced: 5 months ago
JSON representation
A high-performance Swift DNS library built on top of SwiftNIO; aiming to provide DNS client, resolver and server implementations.
- Host: GitHub
- URL: https://github.com/swift-dns/swift-dns
- Owner: swift-dns
- License: apache-2.0
- Created: 2025-06-08T14:06:48.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-12-25T10:54:24.000Z (6 months ago)
- Last Synced: 2025-12-26T23:21:29.061Z (6 months ago)
- Topics: client, dns, server, swift
- Language: Swift
- Homepage:
- Size: 5.95 MB
- Stars: 20
- Watchers: 2
- Forks: 2
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# 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:
```swift
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:
```swift
/// 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
- [x] DNS Parsing
- [x] IDNA support for non-ASCII domain names.
- [x] DNS client
- [x] DNS over UDP
- [x] DNS over TCP
- [ ] DoT (DNS Over TLS)
- [ ] DoH (DNS Over HTTPS)
- [ ] DoQ (DNS Over Quic)
- [ ] MDNS
- [x] DNS resolver
- [x] ForwardingDNSResolver: A DNS client but with caching.
- [ ] \_RecursiveDNSResolver: Implementation is in progress
- [ ] DNS server
- [ ] DNSSEC
## Credits
- https://github.com/apple/swift-nio
- The networking library used to implement this library.
- https://github.com/hickory-dns/hickory-dns
- Some data type / parsing implementations were heavily inspired by hickory-dns.
- https://github.com/valkey-io/valkey-swift
- Helped a lot in putting together an initial version of the connection handling.