micro/resolver/dns/dns.go

78 lines
1.5 KiB
Go
Raw Normal View History

2019-10-08 09:04:13 +01:00
// Package dns resolves names to dns records
package dns
2019-07-28 12:14:40 +01:00
import (
"context"
2019-07-28 12:14:40 +01:00
"net"
"sync"
"time"
2019-07-28 12:14:40 +01:00
"go.unistack.org/micro/v3/resolver"
2019-07-28 12:14:40 +01:00
)
// Resolver is a DNS network resolve
type Resolver struct {
sync.RWMutex
goresolver *net.Resolver
Address string
}
2019-07-28 12:14:40 +01:00
// Resolve tries to resolve endpoint address
2019-07-28 20:00:09 +01:00
func (r *Resolver) Resolve(name string) ([]*resolver.Record, error) {
2019-10-08 09:04:13 +01:00
host, port, err := net.SplitHostPort(name)
if err != nil {
host = name
port = "8085"
}
2019-10-13 18:36:22 +01:00
if len(host) == 0 {
host = "localhost"
}
if len(r.Address) == 0 {
r.Address = "1.1.1.1:53"
}
2019-12-07 23:28:39 +00: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-07 23:28:39 +00:00
}
r.RLock()
goresolver := r.goresolver
r.RUnlock()
if goresolver == nil {
r.Lock()
r.goresolver = &net.Resolver{
Dial: func(ctx context.Context, _ string, _ 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 09:04:13 +01:00
if len(addrs) == 0 {
rec := &resolver.Record{Address: net.JoinHostPort(host, port)}
return []*resolver.Record{rec}, nil
2019-07-28 12:14:40 +01:00
}
2019-10-08 09:04:13 +01:00
records := make([]*resolver.Record, 0, len(addrs))
for _, addr := range addrs {
2019-12-07 23:28:39 +00:00
records = append(records, &resolver.Record{
Address: net.JoinHostPort(addr.String(), port),
2019-12-07 23:28:39 +00:00
})
}
2019-07-28 12:14:40 +01:00
return records, nil
}