Средствами стандартной библиотеки net в Golang можно выполнять резолвинг доменных имен. Следует заметить, что хоть набор функций, таких как LoopkupHost, LookupCNAME, etc… весьма большой, но не самый полный. Если Вам поднадобиться более продвинутая библтотека, то лучше посмотреть на альтернативу - miekg/dns .

Метод разрешения доменных имен, косвенно с помощью таких функций, как Dial , или напрямую с помощью таких функций, как LookupHost и LookupAddr, зависит от операционной системы.

В системах Unix у резолвера есть два варианта разрешения имен. Он может использовать резолвер Go, который отправляет DNS-запросы непосредственно на серверы, перечисленные в /etc/resolv.conf, или он может использовать резолвер на основе cgo, который вызывает подпрограммы библиотеки C, такие как getaddrinfo и getnameinfo.

По умолчанию используется резолвер Go, потому что заблокированный DNS-запрос использует только горутину, а заблокированный вызов C использует поток операционной системы. Когда cgo доступен, резолвер на основе cgo используется вместо этого в различных условиях:

  • в системах, которые не позволяют программам делать прямые DNS-запросы (macOS)
  • когда присутствует переменная среды LOCALDOMAIN (даже если она пуста)
  • когда переменная среды RES_OPTIONS или HOSTALIASES не пуста
  • когда переменная среды ASR_CONFIG не пуста (только OpenBSD)
  • когда /etc/resolv.conf или /etc/nsswitch.conf указывают использование функций, которые не реализует револвер Go
  • и когда искомое имя заканчивается на .local или является именем mDNS

Решение резолвера можно переопределить, установив для параметра netdns переменной среды GODEBUG значение go или cgo, например:

export GODEBUG=netdns=go    # force pure Go resolver
export GODEBUG=netdns=cgo   # force cgo resolver

Решение также можно принудительно выставить при сборке исходного дерева Go, установив тег сборки netgo или netcgo.

Числовое значение netdns, например GODEBUG=netdns=1, заставляет резолвер выводить отладочную информацию о своих решениях. Чтобы принудительно использовать конкретный резолвер при одновременном выводе отладочной информации, соедините два параметра знаком плюс, например GODEBUG=netdns=go+1.

В Plan 9 резолвер всегда обращается к /net/cs и /net/dns.

В Windows резолвер всегда использует функции библиотеки C, такие как GetAddrInfo и DnsQuery.

LookupHost

LookupHost ищет данный хост, используя локальный резолвер. Он возвращает срез адресов этого хоста.

func LookupHost(host string) (addrs []string, err error)

LookupHost использует context.Background внутри; чтобы указать контекст, используйте Resolver.LookupHost.

Пример на macOS:

package main

import (
    "fmt"
    "net"
)

const (
    host string = "mixanemca.ru"
)

func main() {
    addrs, err := net.LookupHost(host)
    if err != nil {
        return
    }

    for _, a := range addrs {
        fmt.Printf("%s %s\n", host, a)
    }
}
$ GODEBUG=netdns=2 go run main.go
go package net: using cgo DNS resolver
go package net: hostLookupOrder(mixanemca.ru) = cgo
mixanemca.ru 134.209.90.80
mixanemca.ru 2a03:b0c0:2:f0::d0:8001
$ GODEBUG=netdns=go+2 go run main.go
go package net: GODEBUG setting forcing use of Go's resolver
go package net: hostLookupOrder(mixanemca.ru) = files,dns
mixanemca.ru 134.209.90.80
mixanemca.ru 2a03:b0c0:2:f0::d0:8001
$ CGO_ENABLED=0 GODEBUG=netdns=2 go run main.go
go package net: built with netgo build tag; using Go's DNS resolver
go package net: hostLookupOrder(mixanemca.ru) = files,dns
mixanemca.ru 134.209.90.80
mixanemca.ru 2a03:b0c0:2:f0::d0:8001

LookupAddr

LookupAddr выполняет обратный поиск заданного адреса, возвращая список имен, сопоставленных с этим адресом.

Возвращаемые имена проверяются на правильность форматирования доменных имен. Если ответ содержит недопустимые имена, эти записи отфильтровываются, и вместе с остальными результатами, если таковые имеются, будет возвращена ошибка.

При использовании резолвера хостовой библиотеки C будет возвращено не более одного результата. Чтобы обойти резолвер хоста, используйте собственный Resolver.

func LookupAddr(addr string) (names []string, err error)

LookupAddr использует context.Background внутри; чтобы указать контекст, используйте Resolver.LookupAddr.

Пример на macOS:

package main

import (
    "fmt"
    "net"
)

const (
    addr string = "1.1.1.1"
)

func main() {
    names, err := net.LookupAddr(addr)
    if err != nil {
        return
    }

    for _, n := range names {
        fmt.Printf("%s %s\n", addr, n)
    }
}
$ GODEBUG=netdns=2 go run main.go
go package net: using cgo DNS resolver
go package net: hostLookupOrder() = cgo
1.1.1.1 one.one.one.one.
$ GODEBUG=netdns=go+2 go run main.go
go package net: GODEBUG setting forcing use of Go's resolver
go package net: hostLookupOrder() = files,dns
1.1.1.1 one.one.one.one.

LookupIP

LookupIP ищет хост, используя локальный резолвер. Он возвращает срез адресов IPv4 и IPv6 этого хоста (в виде net.IP).

func LookupIP(host string) ([]IP, error)

Пример на macOS:

package main

import (
    "fmt"
    "net"
)

const (
    host string = "mixanemca.ru"
)

func main() {
    ips, err := net.LookupIP(host)
    if err != nil {
        return
    }

    for _, ip := range ips {
        fmt.Printf("%s %s\n", host, ip.String())
    }
}
$ GODEBUG=netdns=2 go run main.go
go package net: using cgo DNS resolver
go package net: hostLookupOrder(mixanemca.ru) = cgo
mixanemca.ru 134.209.90.80
mixanemca.ru 2a03:b0c0:2:f0::d0:8001
$ GODEBUG=netdns=go+2 go run main.go
go package net: GODEBUG setting forcing use of Go's resolver
go package net: hostLookupOrder(mixanemca.ru) = files,dns
mixanemca.ru 134.209.90.80
mixanemca.ru 2a03:b0c0:2:f0::d0:8001

Дополнительные материалы