Тип net.Resolver

Тип net.Resolver представляет собой структуру, которая используется для выполнения DNS-запросов с возможностью настройки параметров соединения. В отличие от функций пакета net, которые используют глобальный резолвер по умолчанию, net.Resolver позволяет задать собственный таймаут, указать используемую сеть (например, tcp или udp) и даже использовать собственный механизм разрешения имён через интерфейс Dial.

Основное поле структуры — Dial. Это функция, которая устанавливает соединение с DNS-сервером. Если поле не задано, используется стандартное соединение. Также доступно поле PreferGo, которое заставляет использовать Go-реализацию резолвера вместо системной.

Синтаксис

gotype Resolver struct {
  PreferGo bool
  Dial   func(ctx context.Context, network, address string) (Conn, error)
  // содержит фильтрованные или неэкспортируемые поля
}

Методы типа Resolver

Тип net.Resolver предоставляет несколько методов для выполнения DNS-запросов. Рассмотрим их на примерах.

Пример с LookupHost

Метод LookupHost возвращает список IP-адресов для указанного хоста. Давайте создадим резолвер с кастомным таймаутом и выполним запрос:

gopackage main

import (
  "context"
  "fmt"
  "net"
  "time"
)

func main() {
  resolver := &net.Resolver{
    PreferGo: true,
    Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
      return net.DialTimeout(network, address, 2*time.Second)
    },
  }

  ips, err := resolver.LookupHost(context.Background(), "example.com")
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(ips)
}

Результат выполнения кода:

go[93.184.216.34 2606:2800:220:1:248:1893:25c8:1946]

Пример с LookupIP

Метод LookupIP возвращает список IP-адресов с указанием версии протокола (IPv4 или IPv6). Вот как получить только IPv4-адреса:

gopackage main

import (
  "context"
  "fmt"
  "net"
)

func main() {
  resolver := &net.Resolver{}
  ips, err := resolver.LookupIP(context.Background(), "ip4", "example.com")
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(ips)
}

Результат выполнения кода:

go[93.184.216.34]

Пример с LookupCNAME

Метод LookupCNAME возвращает каноническое имя для указанного хоста. Если такого имени нет, возвращается исходное имя:

gopackage main

import (
  "context"
  "fmt"
  "net"
)

func main() {
  resolver := &net.Resolver{}
  cname, err := resolver.LookupCNAME(context.Background(), "www.example.com")
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(cname)
}

Результат выполнения кода:

go"example.com"

Пример с LookupMX

Метод LookupMX возвращает список MX-записей для указанного домена. Каждая запись содержит имя почтового сервера и его приоритет:

gopackage main

import (
  "context"
  "fmt"
  "net"
)

func main() {
  resolver := &net.Resolver{}
  mxRecords, err := resolver.LookupMX(context.Background(), "example.com")
  if err != nil {
    fmt.Println(err)
    return
  }
  for _, mx := range mxRecords {
    fmt.Printf("%s %d\n", mx.Host, mx.Pref)
  }
}

Результат выполнения кода:

go"mail.example.com 10"
"backup.example.com 20"

Смотрите также

  • тип net.Dialer,
    который настраивает соединения для сетевых операций
  • функцию net.LookupHost,
    которая ищет IP-адреса хоста через глобальный резолвер
  • функцию net.LookupMX,
    которая получает MX-записи через глобальный резолвер
  • функцию net.LookupCNAME,
    которая получает каноническое имя через глобальный резолвер