silk.net.dns.client_native.
Ask DNS servers questions from a native program, with system UDP and TCP sockets.
When to use#
Use a NativeDnsClient to look up any record type, such as MX or TXT, in a program without an
event loop. It blocks the thread until the answer comes or the last try ends. To use your own
sockets or loop, drive a silk.net.dns.query.Exchange instead. To turn a host name into
addresses with the system rules, such as /etc/hosts, use silk.net.resolver_native.
Details#
NativeDnsClient.query drives an Exchange with the servers and options of a
ResolverConfig. Each server gets its own connected UDP socket, so the system drops datagrams
that come from another address. A TCP try opens a new connection with silk.net.socket_native.
Query identifiers come from the Random service.
Examples#
Ask a test server#
This program starts no server, so the query fails with Unreachable or Timeout.
import silk.mem.allocator { Allocator, OutOfMemoryError }
import silk.collections.list { List }
import silk.core.effect { Effect }
import silk.core.result { Result }
import silk.net.address { Endpoint, IpAddress, Ipv4Address, Port }
import silk.net.dns.client_native { NativeDnsClient }
import silk.net.dns.config { ResolverConfig }
import silk.net.dns.message { CLASS_IN, MessageError, Name, Question, TYPE_A }
import silk.net.dns.query { QueryError, Reply }
import silk.system.monotonic_clock { MonotonicClock }
import silk.system.monotonic_clock_native { OsMonotonicClock }
import silk.system.random { Random }
import silk.system.random_native { OsRandom }
effect fn program() -> i32
! MessageError | OutOfMemoryError
? &mut Allocator | &mut MonotonicClock | &mut Random {
let mut servers = List<Endpoint>.make()
let loopback = IpAddress.V4 { value: Ipv4Address.fromOctets([127, 0, 0, 1]) }
run List<Endpoint>.append(&mut servers, Endpoint.make(loopback, Port.fromU16(9)))
let mut config = ResolverConfig.make(move servers)
config.timeout = 100000000
config.attempts = 1
let name = match Name.parse("example.com") {
Result<Name, MessageError>.Success { value } => value
Result<Name, MessageError>.Failure {..} => {
return 1
}
}
let mut client = NativeDnsClient.make(move config)
let result = run Effect.result(NativeDnsClient.query(
&mut client,
Question { name: name, kind: TYPE_A, class: CLASS_IN },
))
return match move result {
Result<Reply, QueryError | MessageError | OutOfMemoryError>.Success {..} => 1
Result<Reply, QueryError | MessageError | OutOfMemoryError>.Failure {..} => 0
}
}
effect fn failed<E>(error: E) -> i32 {
drop error
return 1
}
pub fn main() -> i32 {
let mut allocator = Allocator.systemAllocatorProvider()
let mut clock = OsMonotonicClock.make()
let mut random = OsRandom.make()
return run Effect.catchAll(program(), failed)
|> Effect.provideMut<Allocator>(&mut allocator)
|> Effect.provideMut<MonotonicClock>(&mut clock)
|> Effect.provideMut<Random>(&mut random)
}Import as NativeDnsClient with import silk.net.dns.client_native { NativeDnsClient }.
Public declarations: 1.
NativeDnsClient#
pub struct NativeDnsClientA blocking DNS client for native programs.
Details#
The client keeps its ResolverConfig. With the rotate option, each query starts at the next
server.
Implementation NativeDnsClient#
impl NativeDnsClientAssociated function make#
pub fn make(config: ResolverConfig) -> NativeDnsClientReturns a client for config.
Method config#
pub fn config(self: &Self) -> &ResolverConfigReturns the configuration of the client.
Method query#
pub effect fn query(self: &mut Self, question: Question) -> Reply
! QueryError | MessageError | OutOfMemoryError
? &mut Allocator | &mut MonotonicClock | &mut RandomAsks question and returns the answer.
Details#
The reply can have any response code other than SERVFAIL, NOTIMP, REFUSED and FORMERR, such as
RCODE_NAME_ERROR for a name that does not exist. Check reply.message.header.responseCode.
A server that cannot be reached, because a socket cannot be opened or a send fails, is skipped.
Errors#
QueryErrorif no server answered:Timeout,NoServers, or the last problem that a server reported.MessageErrorif the question does not fit in a message.OutOfMemoryErrorif theAllocatorcannot supply the packets or the reply.
Category: Networking.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2, x86_64-pc-windows-msvc, wasm64-unknown-unknown.