A pure Nim Domain Name System (DNS) client implemented with dnsprotocol.
This implementation has synchronous and asynchronous (async) procedures (procs) for transmitting data over the internet, using both UDP and TCP protocol.
Basic Use
Resolving IPv4 addresses for nim-lang.org (not async):
import ndns let client = initDnsClient() echo resolveIpv4(client, "nim-lang.org")
Resolving IPv4 addresses for nim-lang.org (async):
import asyncdispatch, ndns let client = initDnsClient() echo waitFor asyncResolveIpv4(client, "nim-lang.org")
Advanced Use
Creating a Message object with a QType.A query for the domain name nim-lang.org, transmitting the Message and receiving the response (not async):
import ndns let header = initHeader(randId(), rd = true) let question = initQuestion("nim-lang.org", QType.A, QClass.IN) # If the last character of "nim-lang.org" is not a '.', the initializer will # add, as it is called the DNS root. let msg = initMessage(header, @[question]) # The initializer automatically changes `header.qdcount` to `1'u16` let client = initDnsClient() var rmsg = dnsQuery(client, msg) echo repr(rmsg)
Creating a Message object with a QType.A query for the domain name nim-lang.org, transmitting the Message and receiving the response (async):
import asyncdispatch, ndns let header = initHeader(randId(), rd = true) let question = initQuestion("nim-lang.org", QType.A, QClass.IN) # If the last character of "nim-lang.org" is not a '.', the initializer will # add, as it is called the DNS root. let msg = initMessage(header, @[question]) # The initializer automatically changes `header.qdcount` to `1'u16` let client = initDnsClient() var rmsg = waitFor dnsAsyncQuery(client, msg) echo repr(rmsg)
Using System DNS Server
You can initialize the DNS client with the DNS resolver server used by the system. To do this, start the client with initSystemDnsClient.
import ndns let client = initSystemDnsClient() echo resolveIpv4(client, "nim-lang.org")See initSystemDnsClient() for supported platforms.
Types
DnsClient = object ip*: string ## Dns server IP. **In the future, this field will no longer be exportable. ## Use `getIp()`.** port*: Port ## DNS server listening port. **In the future, this field will no longer be ## exportable. Use `getPort()`.** domain: Domain
- Contains information about the DNS server. Source Edit
IsNotAnResponseError = object of CatchableError
- Raised if not a response (!= QR.Response). Source Edit
OpCodeNotEqualError = object of CatchableError
- Raised if the OpCode is different between the query and the response. Source Edit
ResponseIdNotEqualError = object of CatchableError
- Raised if the query ID does not match the response ID. Source Edit
ResponseIpNotEqualError = object of CatchableError
- Raised if the IP that sent the response is different from the IP that received the query (only UDP). Source Edit
ResponsePortNotEqualError = object of CatchableError
- Raised if the Port that sent the response is different from the Port that received the query (only UDP). Source Edit
UnexpectedDisconnectionError = object of CatchableError
- Raised if an unexpected disconnect occurs (only TCP). Source Edit
Consts
defaultIpDns {....deprecated: "Use `ndnsDnsServerIp`".} = "8.8.8.8"
- Default dns server ip for DNS queries. The Google server was chosen due to its uptime, with the same IP. Source Edit
ndnsDnsServerIp {.strdefine.} = "8.8.8.8"
- Default dns server ip for queries. You can change by compiling with -d:ndnsDnsServerIp=1.1.1.1. Source Edit
Procs
proc asyncResolveDnsBL(client: DnsClient; ip, dnsbl: string; timeout: int = 500): owned( Future[seq[string]]) {....stackTrace: false, raises: [Exception, ValueError], tags: [ WriteIOEffect, RootEffect, TimeEffect, ReadIOEffect], forbids: [].}
-
Returns IPv4 addresses. Usually the loopback address (127.0.0.0/24), in which the last octet of IPv4 represents something on the black list.
Parameters
- client is a DnsClient object that contains the IP and Port of the DNS server.
- ip is the IPv4 or IPv6 address that you want to know if it is blacklisted.
- dnsbl is the domain name for DnsBL queries.
- timeout is the maximum waiting time, in milliseconds, to connect to the DNS server or to receive the response from the DNS server. When it is negative (less than 0), it will try to connect for an unlimited time or to receive the response for an unlimited time.
proc asyncResolveIpv4(client: DnsClient; domain: string; timeout: int = 500): owned( Future[seq[string]]) {....stackTrace: false, raises: [Exception, ValueError], tags: [ WriteIOEffect, RootEffect, TimeEffect, ReadIOEffect], forbids: [].}
-
Returns all IPv4 addresses, in a seq[string], that have been resolved from domain. The seq[string] can be empty.
Parameters
- client is a DnsClient object that contains the IP and Port of the DNS server.
- domain is the domain name that you wish to obtain IPv4 addresses.
- timeout is the maximum waiting time, in milliseconds, to connect to the DNS server or to receive the response from the DNS server. When it is negative (less than 0), it will try to connect for an unlimited time or to receive the response for an unlimited time.
proc asyncResolveIpv6(client: DnsClient; domain: string; timeout: int = 500): owned( Future[seq[string]]) {....stackTrace: false, raises: [Exception, ValueError], tags: [ WriteIOEffect, RootEffect, TimeEffect, ReadIOEffect], forbids: [].}
-
Returns all IPv6 addresses, in a seq[string], that have been resolved from domain. The seq[string] can be empty.
Parameters
- client is a DnsClient object that contains the IP and Port of the DNS server.
- domain is the domain name that you wish to obtain IPv6 addresses.
- timeout is the maximum waiting time, in milliseconds, to connect to the DNS server or to receive the response from the DNS server. When it is negative (less than 0), it will try to connect for an unlimited time or to receive the response for an unlimited time.
proc asyncResolveRDns(client: DnsClient; ip: string; timeout: int = 500): owned( Future[seq[string]]) {....stackTrace: false, raises: [Exception, ValueError], tags: [ WriteIOEffect, RootEffect, TimeEffect, ReadIOEffect], forbids: [].}
-
Returns all domain names, in a seq[string], which is obtained by the "reverse" query of ip. The seq[string] can be empty.
Parameters
- client is a DnsClient object that contains the IP and Port of the DNS server.
- ip is the IPv4 or IPv6 address that is intended to obtain the domain name, which represents the reverse address.
- timeout is the maximum waiting time, in milliseconds, to connect to the DNS server or to receive the response from the DNS server. When it is negative (less than 0), it will try to connect for an unlimited time or to receive the response for an unlimited time.
proc dnsAsyncQuery(client: DnsClient; msg: Message; timeout: int = 500; retransmit = false): owned(Future[Message]) {. ...stackTrace: false, raises: [Exception, ValueError], tags: [WriteIOEffect, RootEffect, TimeEffect, ReadIOEffect], forbids: [].}
-
Returns a Message of the DNS query response performed using the UDP protocol.
Parameters
- client is a DnsClient object that contains the IP and Port of the DNS server.
- msg is a Message object that contains the DNS query.
- timeout is the maximum waiting time, in milliseconds, to receive the response from the DNS server. When it is negative (less than 0), it will try to receive the response for an unlimited time.
- retransmit when true, determine the retransmission of the query to TCP protocol when the received response is truncated (header.flags.tc == true).
proc dnsAsyncTcpQuery(client: DnsClient; msg: Message; timeout: int = 500): owned( Future[Message]) {....stackTrace: false, raises: [Exception, ValueError], tags: [ WriteIOEffect, RootEffect, TimeEffect, ReadIOEffect], forbids: [].}
-
Returns a Message of the DNS query response performed using the TCP protocol
Parameters
- client is a DnsClient object that contains the IP and Port of the DNS server.
- msg is a Message object that contains the DNS query.
- timeout is the maximum waiting time, in milliseconds, to connect to the DNS server. When it is negative (less than 0), it will try to connect for an unlimited time.
proc dnsQuery(client: DnsClient; msg: Message; timeout: int = -1; retransmit = false): Message {....raises: [IOError, OSError, ValueError, KeyError, Exception, LibraryError, SslError, TimeoutError, ResponseIpNotEqualError, ResponsePortNotEqualError, ResponseIdNotEqualError, IsNotAnResponseError, OpCodeNotEqualError, UnexpectedDisconnectionError], tags: [WriteIOEffect, RootEffect, ReadIOEffect, TimeEffect], forbids: [].}
-
Returns a Message of the DNS query response performed using the UDP protocol
Parameters
- client is a DnsClient object that contains the IP and Port of the DNS server.
- msg is a Message object that contains the DNS query.
- timeout is the maximum waiting time, in milliseconds, to receive the response from the DNS server. When it is -1, it will try to receive the response for an unlimited time.
- retransmit when true, determine the retransmission of the query to TCP protocol when the received response is truncated (header.flags.tc == true).
proc dnsTcpQuery(client: DnsClient; msg: Message; timeout: int = -1): Message {....raises: [ IOError, OSError, ValueError, KeyError, Exception, LibraryError, Exception, SslError, OSError, TimeoutError, UnexpectedDisconnectionError, ResponseIdNotEqualError, IsNotAnResponseError, OpCodeNotEqualError], tags: [WriteIOEffect, RootEffect, ReadIOEffect, TimeEffect], forbids: [].}
-
Returns a Message of the DNS query response performed using the TCP protocol.
Parameters
- client is a DnsClient object that contains the IP and Port of the DNS server.
- msg is a Message object that contains the DNS query.
- timeout is the maximum waiting time, in milliseconds, to connect to the DNS server. When it is -1, it will try to connect for an unlimited time.
proc initDnsClient(ip: string = ndnsDnsServerIp; port: Port = Port(53)): DnsClient {. ...raises: [ValueError], tags: [], forbids: [].}
-
Returns a created DnsClient object.
Parameters
- ip is a DNS server IP. It can be IPv4 or IPv6. It cannot be a domain name.
- port is a DNS server listening port.
proc initSystemDnsClient(): DnsClient {....raises: [CatchableError], tags: [], forbids: [].}
-
Returns a DnsClient object, in which the dns server IP is the first one used by the system. If it is not possible to determine a dns server IP by the system, it will be initialized with ndnsDnsServerIp.
Currently implemented for:
Notes:
- If your platform is not listed above and uses a resolver configuration file, compile with -d:ndnsUseResolver.
- It just creates a DnsClient object with the IP used by the system. Does not use the system's native DNS resolution implementation unless the system provides a proxy.
- The ip field in the DnsClient object does not change automatically if the IP used by the system changes.
proc prepareDnsBL(ip, dnsbl: string): string {....raises: [ValueError], tags: [], forbids: [].}
-
Returns a domain name for DnsBL query.
Parameters
- ip is the IP address you want to query. It can be an IPv4 or IPv6. It cannot be a domain name.
- dnsbl is the domain name that maintains the blacklist.
proc prepareRDns(ip: string): string {....raises: [ValueError], tags: [], forbids: [].}
-
Returns a domain name for reverse DNS lookup.
Parameters
- ip is the IP address you want to query. It can be an IPv4 or IPv6. It cannot be a domain name.
proc resolveDnsBL(client: DnsClient; ip, dnsbl: string; timeout: int = -1): seq[ string] {....raises: [ValueError, IOError, OSError, KeyError, Exception, LibraryError, SslError, TimeoutError, ResponseIpNotEqualError, ResponsePortNotEqualError, ResponseIdNotEqualError, IsNotAnResponseError, OpCodeNotEqualError, UnexpectedDisconnectionError], tags: [WriteIOEffect, RootEffect, ReadIOEffect, TimeEffect], forbids: [].}
-
Returns IPv4 addresses. Usually the loopback address (127.0.0.0/24), in which the last octet of IPv4 represents something on the black list.
Parameters
- client is a DnsClient object that contains the IP and Port of the DNS server.
- ip is the IPv4 or IPv6 address that you want to know if it is blacklisted.
- dnsbl is the domain name for DnsBL queries.
- timeout is the maximum waiting time, in milliseconds, to connect to the DNS server or to receive the response from the DNS server. When it is -1, it will try to connect for an unlimited time or to receive the response for an unlimited time.
proc resolveIpv4(client: DnsClient; domain: string; timeout: int = -1): seq[ string] {....raises: [ValueError, IOError, OSError, KeyError, Exception, LibraryError, SslError, TimeoutError, ResponseIpNotEqualError, ResponsePortNotEqualError, ResponseIdNotEqualError, IsNotAnResponseError, OpCodeNotEqualError, UnexpectedDisconnectionError], tags: [WriteIOEffect, RootEffect, ReadIOEffect, TimeEffect], forbids: [].}
-
Returns all IPv4 addresses, in a seq[string], that have been resolved from domain. The seq[string] can be empty.
Parameters
- client is a DnsClient object that contains the IP and Port of the DNS server.
- domain is the domain name that you wish to obtain IPv4 addresses.
- timeout is the maximum waiting time, in milliseconds, to connect to the DNS server or to receive the response from the DNS server. When it is -1, it will try to connect for an unlimited time or to receive the response for an unlimited time.
proc resolveIpv6(client: DnsClient; domain: string; timeout: int = -1): seq[ string] {....raises: [ValueError, IOError, OSError, KeyError, Exception, LibraryError, SslError, TimeoutError, ResponseIpNotEqualError, ResponsePortNotEqualError, ResponseIdNotEqualError, IsNotAnResponseError, OpCodeNotEqualError, UnexpectedDisconnectionError], tags: [WriteIOEffect, RootEffect, ReadIOEffect, TimeEffect], forbids: [].}
-
Returns all IPv6 addresses, in a seq[string], that have been resolved from domain. The seq[string] can be empty.
Parameters
- client is a DnsClient object that contains the IP and Port of the DNS server.
- domain is the domain name that you wish to obtain IPv6 addresses.
- timeout is the maximum waiting time, in milliseconds, to connect to the DNS server or to receive the response from the DNS server. When it is -1, it will try to connect for an unlimited time or to receive the response for an unlimited time.
proc resolveRDns(client: DnsClient; ip: string; timeout: int = -1): seq[string] {....raises: [ ValueError, IOError, OSError, KeyError, Exception, LibraryError, SslError, TimeoutError, ResponseIpNotEqualError, ResponsePortNotEqualError, ResponseIdNotEqualError, IsNotAnResponseError, OpCodeNotEqualError, UnexpectedDisconnectionError], tags: [WriteIOEffect, RootEffect, ReadIOEffect, TimeEffect], forbids: [].}
-
Returns all domain names, in a seq[string], which is obtained by the "reverse" query of ip. The seq[string] can be empty.
Parameters
- client is a DnsClient object that contains the IP and Port of the DNS server.
- ip is the IPv4 or IPv6 address that is intended to obtain the domain name, which represents the reverse address.
- timeout is the maximum waiting time, in milliseconds, to connect to the DNS server or to receive the response from the DNS server. When it is -1, it will try to connect for an unlimited time or to receive the response for an unlimited time.