Skip to content

a high-performance library containing types representing an endpoint, such as DomainName and IPv4/v6Address

License

Notifications You must be signed in to change notification settings

swift-dns/swift-endpoint

Repository files navigation

Unit Tests CI Benchamrks CI Swift 6.2+

swift-endpoint

swift-endpoint is a high-performance package containing types representing an endpoint and related utilities.

The package contains a great amount of unit tests as well as benchmarks to ensure correctness and high performance.

Implementations

  • DomainName
    • Unicode-17-compliant IDNA support for non-ASCII domain names.
  • IPv4Address, IPv6Address, AnyIPAddress
  • CIDR
  • UnixDomainSocketAddress

Usage

swift-endpoint provides highly optimized implementations for converting its types to and from an String.

You can either initialize each type using an String, or initialize the exact underlying type they contain.

Here are some examples:

import Endpoint

/// Define a domain name. The type will parse the domain name and store it in DNS wire-format internally.
let domainName1 = try DomainName("mahdibm.com")
print(domainName1) /// prints "mahdibm.com"

/// Define a non-ASCII domain.
let domainName2 = try DomainName("新华网.中国")
print(domainName2) /// prints "新华网.中国"
print(domainName2.debugDescription) /// prints "xn--xkrr14bows.xn--fiqs8s"

/// Define a domain name containing an ip address.
let domainName3 = try DomainName("255.255.255.255")
print(domainName3) /// prints "255.255.255.255"

/// Define an ipv4 address. The type will parse the ip address into a UInt32 internally.
let ipv4Address1 = IPv4Address("127.0.0.1")!
let ipv4Address2 = IPv4Address(192, 168, 1, 1)!
print(ipv4Address1) /// prints "127.0.0.1"
print(ipv4Address2) /// prints "192.168.1.1"

/// Define an ipv6 address. The type will parse the ip address into a UInt128 internally.
let ipv6Address1 = IPv6Address("[FF::]")!
let ipv6Address2 = IPv6Address("2001:db8:85a3:0:0:0:0:100")!
let ipv6Address3 = IPv6Address("::FFFF:204.152.189.116")!
/// Prints the ipv6 representations according to RFC 5952
print(ipv6Address1) /// prints "[ff::]"
print(ipv6Address2) /// prints "[2001:db8:85a3::100]"
print(ipv6Address3) /// prints "[::ffff:cc98:bd74]"

/// Define an any-ip-address. The type will automatically parse the ip address into the corrext type.
let anyIPv4Address = AnyIPAddress("192.168.1.1")
let anyIPv6Address = AnyIPAddress("[2001:DB8:85A3::100]")
print(anyIPv4Address) /// prints "192.168.1.1"
print(anyIPv6Address) /// prints "[2001:db8:85a3::100]"

/// Define a CIDR. The type will store a `prefix` and a `mask`, representing this block of ips.
let cidr1 = CIDR(prefix: ipv4Address1, prefixLength: 8) /// ipv4Address1 == "127.0.0.1"
let cidr2 = CIDR<IPv4Address>("192.168.1.1")!
let containmentCheck1 = cidr1.contains(ipv4Address2) /// ipv4Address2 == "192.168.1.1"
let containmentCheck2 = cidr2.contains(ipv4Address2) /// ipv4Address2 == "192.168.1.1"
print(cidr1) /// prints "127.0.0.0/8"
print(cidr2) /// prints "192.168.1.1/32"
print(containmentCheck1) /// prints "false"
print(containmentCheck2) /// prints "true"

Type Conversions

All types are convertible to each other in a performant way. Some examples:

import Endpoint

let ipInDomainName = try DomainName("255.255.255.255")

let fastIPv4 = IPv4Address(domainName: ipInDomainName)! /// ✅ Converts the domain into the equivalent ipv4 address
let slowIPv4 = IPv4Address(ipInDomainName.description)! /// ❌ This does work, but has worse performance

let fastIPv4Conversion = try DomainName(ipv4: fastIPv4)! /// ✅ Converts the ipv4 into the equivalent domain name
let slowIPv4Conversion = DomainName(fastIPv4.description)! /// ❌ This does work, but has worse performance

let anyIPAddress = AnyIPAddress(domainName: ipInDomainName)
print(anyIPAddress) /// prints "255.255.255.255"

Performance

To see up to date information about performance of this package, please go to this benchmarks list, and choose the most recent benchmark. You'll see a summary of the benchmark there.

In this post on the Swift forums I was asked to compare IP parsing implementations with the native C libraries which provide functions such as inet_ntop and inet_pton which are commonly used by everyone, including swift-nio.

Here's the result at that point in time. Note that I made a lot of effort to make sure the C related functions are performing at their best.

All benchmarks on all platforms commit similar allocations. 3 of the benchmarks always do 0, IPv6_String_Encoding_Mixed always does 1.

In all benchmarks apart from 1, this library performs better than the C libraries. On the "IPv6 string decoding" benchmark it performs only 30% worse than Glibc, at ~23 millions rounds per second.

The results are all reproducible by simply running scripts/benchmark.bash on a machine of your own.

Against Darwin

These were performed on my M1 Pro MacBook, on macOS 26.0.

Benchmark Name Rounds Swift inet_pton/ntop
IPv4_String_Encoding_Mixed 15 Millions 153ms 3036ms
IPv4_String_Decoding_Local_Broadcast 10 Millions 251ms 468ms
IPv6_String_Encoding_Mixed 4 Millions 281ms 1473ms
IPv6_String_Decoding_2_Groups_Compressed_In_The_Middle 3 Millions 180ms 360ms

Against Glibc

These were performed on a dedicated-cpu-core machine from Hetzner in the Falkenstein region.

Host 'eba52b5e61ab' with 2 'x86_64' processors with 7 GB memory, running: #85-Ubuntu SMP PREEMPT_DYNAMIC Thu Sep 18 15:26:59 UTC 2025

Benchmark Name Rounds Swift inet_pton/ntop
IPv4_String_Encoding_Mixed 15 Millions 190ms 1570ms
IPv4_String_Decoding_Local_Broadcast 10 Millions 180ms 240ms
IPv6_String_Encoding_Mixed 4 Millions 200ms 1830ms
IPv6_String_Decoding_2_Groups_Compressed_In_The_Middle 3 Millions 130ms 100ms

About

a high-performance library containing types representing an endpoint, such as DomainName and IPv4/v6Address

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •