Network addresses and resolution
Owned IP, domain, endpoint, and finite provider-replaceable resolution contracts.
Use silk.network_address to parse and retain origin hosts, and silk.resolver to turn an owned
host and port into a finite owned endpoint sequence. The portable actors work without libc and can
use deterministic Resolver providers in tests and embedded applications.
import silk.network_address {AddressError, Host, Port}
import silk.result {Result}
pub fn main() -> i32 {
let host = Host.parse(b"[2001:db8::1]")
let port = Port.make(443)
return match move host {
Result<Host, AddressError>.Failure {error} => 1
Result<Host, AddressError>.Success {value} => match move port {
Result<Port, AddressError>.Failure {error} => 2
Result<Port, AddressError>.Success {value: admitted} => {
if Port.value(&admitted) == 443 { return 42 }
return 3
}
}
}
}Owned values
Ipv4Address and Ipv6Address own network-order octets. Their parsers reject legacy libc IPv4
forms, zones, and IPvFuture syntax. formatInto writes canonical text into caller-owned storage;
the Display implementations stream that canonical form through the current Writer.
DomainHost.make copies at most 253 bytes of prepared ASCII LDH/A-label spelling. It rejects empty
labels, edge hyphens, trailing dots, NUL, non-ASCII bytes, an all-decimal final label, and an
xn-- label whose payload is not syntactically valid RFC 3492 Punycode. Equality is ASCII
case-insensitive while display preserves the admitted spelling. This is syntax admission for an
already prepared ASCII A-label: Unicode-to-ASCII mapping, normalization, IDNA code-point tables,
contextual and bidirectional rules, and search-suffix expansion are outside this profile.
Host.parse classifies bracketed IPv6 and strict IPv4 before admitting a domain. The resulting Host
is the origin identity: resolution never replaces it with a CNAME, reverse lookup, or endpoint.
Finite requests and results
Create a ResolveRequest with an owned Host, checked Port, Any/V4/V6 family selection,
maxResults, and an optional absolute monotonic Instant. maxResults must be from 1 through 64.
Resolver.resolve handles numeric hosts without invoking the Resolver provider. When a numeric
request carries a deadline, it samples MonotonicClock exactly once and treats an equal or past mark
as Timeout. A successful numeric result contains one endpoint after family filtering.
Domain requests dispatch to the lexically supplied Resolver service. Before publication,
Resolver.resolve re-admits every provider endpoint through the requested family selection,
stable exact deduplication, and the caller's capacity. Wrong-family and duplicate candidates do not
consume capacity; the next matching distinct endpoint beyond maxResults fails LimitExceeded
instead of silently truncating. An empty admitted result fails NoAddress. Allocation refusal
remains OutOfMemoryError.
A provider that accepts a domain deadline can inspect the owned copy returned by
ResolveRequest.deadline. It must compare the deadline before query allocation or registration,
and bracket any parked work so cancellation releases its registration, sole affine Wake, and
result owner. A provider that cannot provide that lifecycle must return DeadlineUnsupported
before observable work.
NativeSystemResolver
silk.native_resolver is selected only for Darwin ARM64 system libc and GNU Linux x86-64/ARM64 GNU
libc. It is deliberately synchronous.
- Domain plus
Some(deadline)failsDeadlineUnsupportedbefore clock sampling, allocation, query construction, or libc work. - Domain plus
Nonemakes exactly one blockinggetaddrinfocall using a root-terminated name, decimal service, explicit address family, stream socket, TCP protocol, and numeric-service hint. - Every successful non-null addrinfo chain has one move-only owner. It is released exactly once after success or any later typed failure, including invalid shape, result-limit exhaustion, and Silk allocation refusal.
Once getaddrinfo begins, the operation has no cancellation or timeout boundary. It can block the
calling host thread, sibling fibers, and timers indefinitely. The 64-endpoint public bound limits
only published results; it does not bound libc allocation, NSS traversal, DNS activity, elapsed
time, scheduler blockage, or process memory. Use a different Resolver provider when DNS itself must
honor a deadline and structured cancellation.
Errors
Resolution distinguishes invalid request input, unsupported forms, timeout, unsupported deadline,
no admitted address, name lookup failure, temporary failure, unsupported family, system resources,
result-limit exhaustion, malformed native results, and wrapped native failure. NameNotFound
describes the libc result and does not claim that a DNS NXDOMAIN packet was observed.
HTTP integration
The streaming HTTP client owns translation into its public error vocabulary. JUL-23 must catch
ResolverError.DeadlineUnsupported at the hostname-resolution dispatch boundary and return
HttpClientError.UnsupportedDeadline before starting a hostname connection. Numeric origins keep
the caller's absolute monotonic deadline through resolution and connection setup; the Resolver
actors do not translate, discard, or replace it.