Средствами стандартной библиотеки 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