src/ndns

Search:
Group by:
Source   Edit  

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.
Source   Edit  
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.
Source   Edit  
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.
Source   Edit  
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.
Source   Edit  
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).
Source   Edit  
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.
Source   Edit  
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).
Source   Edit  
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.
Source   Edit  
proc getIp(client: DnsClient): string {....raises: [], tags: [], forbids: [].}

Returns the IP defined in the client.

Give preference to this procedure than client.ip, as it will be deprecated in the future.

Source   Edit  
proc getPort(client: DnsClient): Port {....raises: [], tags: [], forbids: [].}

Returns the port defined in the client.

Give preference to this procedure than client.port, as it will be deprecated in the future.

Source   Edit  
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.
Source   Edit  
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.
Source   Edit  
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.
Source   Edit  
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.
Source   Edit  
proc randId(): uint16 {.inline, ...raises: [], tags: [], forbids: [].}
Returns a uint16, randomly generated, to be used as an id. Source   Edit  
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.
Source   Edit  
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.
Source   Edit  
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.
Source   Edit  
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.
Source   Edit