micro/resolver/dns/dns.go

79 lines
1.5 KiB
Go
Raw Normal View History

2019-10-08 11:04:13 +03:00
// Package dns resolves names to dns records
2019-07-28 14:14:40 +03:00
package dns
import (
"context"
2019-07-28 14:14:40 +03:00
"net"
"sync"
"time"
2019-07-28 14:14:40 +03:00
"github.com/unistack-org/micro/v3/resolver"
2019-07-28 14:14:40 +03:00
)
// Resolver is a DNS network resolve
type Resolver struct {
// The resolver address to use
Address string
goresolver *net.Resolver
sync.RWMutex
}
2019-07-28 14:14:40 +03:00
// Resolve tries to resolve endpoint address
2019-07-28 22:00:09 +03:00
func (r *Resolver) Resolve(name string) ([]*resolver.Record, error) {
2019-10-08 11:04:13 +03:00
host, port, err := net.SplitHostPort(name)
if err != nil {
host = name
port = "8085"
}
2019-10-13 20:36:22 +03:00
if len(host) == 0 {
host = "localhost"
}
if len(r.Address) == 0 {
r.Address = "1.1.1.1:53"
}
2019-12-08 02:28:39 +03:00
// parsed an actual ip
if v := net.ParseIP(host); v != nil {
rec := &resolver.Record{Address: net.JoinHostPort(host, port)}
return []*resolver.Record{rec}, nil
2019-12-08 02:28:39 +03:00
}
r.RLock()
goresolver := r.goresolver
r.RUnlock()
if goresolver == nil {
r.Lock()
r.goresolver = &net.Resolver{
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{
Timeout: time.Millisecond * time.Duration(100),
}
return d.DialContext(ctx, "udp", r.Address)
},
}
r.Unlock()
}
addrs, err := goresolver.LookupIP(context.TODO(), "ip", host)
if err != nil {
return nil, err
}
2019-10-08 11:04:13 +03:00
if len(addrs) == 0 {
rec := &resolver.Record{Address: net.JoinHostPort(host, port)}
return []*resolver.Record{rec}, nil
2019-07-28 14:14:40 +03:00
}
2019-10-08 11:04:13 +03:00
records := make([]*resolver.Record, 0, len(addrs))
for _, addr := range addrs {
2019-12-08 02:28:39 +03:00
records = append(records, &resolver.Record{
Address: net.JoinHostPort(addr.String(), port),
2019-12-08 02:28:39 +03:00
})
}
2019-07-28 14:14:40 +03:00
return records, nil
}