github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/network/resolver/dns/dns.go (about)

     1  // Licensed under the Apache License, Version 2.0 (the "License");
     2  // you may not use this file except in compliance with the License.
     3  // You may obtain a copy of the License at
     4  //
     5  //     https://www.apache.org/licenses/LICENSE-2.0
     6  //
     7  // Unless required by applicable law or agreed to in writing, software
     8  // distributed under the License is distributed on an "AS IS" BASIS,
     9  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    10  // See the License for the specific language governing permissions and
    11  // limitations under the License.
    12  //
    13  // Original source: github.com/micro/go-micro/v3/network/resolver/dns/dns.go
    14  
    15  // Package dns resolves names to dns records
    16  package dns
    17  
    18  import (
    19  	"context"
    20  	"net"
    21  
    22  	"github.com/tickoalcantara12/micro/v3/service/network/resolver"
    23  	"github.com/miekg/dns"
    24  )
    25  
    26  // Resolver is a DNS network resolve
    27  type Resolver struct {
    28  	// The resolver address to use
    29  	Address string
    30  }
    31  
    32  // Resolve assumes ID is a domain name e.g micro.mu
    33  func (r *Resolver) Resolve(name string) ([]*resolver.Record, error) {
    34  	host, port, err := net.SplitHostPort(name)
    35  	if err != nil {
    36  		host = name
    37  		port = "8085"
    38  	}
    39  
    40  	if len(host) == 0 {
    41  		host = "localhost"
    42  	}
    43  
    44  	if len(r.Address) == 0 {
    45  		r.Address = "1.0.0.1:53"
    46  	}
    47  
    48  	//nolint:prealloc
    49  	var records []*resolver.Record
    50  
    51  	// parsed an actual ip
    52  	if v := net.ParseIP(host); v != nil {
    53  		records = append(records, &resolver.Record{
    54  			Address: net.JoinHostPort(host, port),
    55  		})
    56  		return records, nil
    57  	}
    58  
    59  	m := new(dns.Msg)
    60  	m.SetQuestion(dns.Fqdn(host), dns.TypeA)
    61  	rec, err := dns.ExchangeContext(context.Background(), m, r.Address)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  
    66  	for _, answer := range rec.Answer {
    67  		h := answer.Header()
    68  		// check record type matches
    69  		if h.Rrtype != dns.TypeA {
    70  			continue
    71  		}
    72  
    73  		arec, _ := answer.(*dns.A)
    74  		addr := arec.A.String()
    75  
    76  		// join resolved record with port
    77  		address := net.JoinHostPort(addr, port)
    78  		// append to record set
    79  		records = append(records, &resolver.Record{
    80  			Address: address,
    81  		})
    82  	}
    83  
    84  	// no records returned so just best effort it
    85  	if len(records) == 0 {
    86  		records = append(records, &resolver.Record{
    87  			Address: net.JoinHostPort(host, port),
    88  		})
    89  	}
    90  
    91  	return records, nil
    92  }