go-micro.dev/v5@v5.12.0/util/mdns/dns_sd.go (about)

     1  package mdns
     2  
     3  import "github.com/miekg/dns"
     4  
     5  // DNSSDService is a service that complies with the DNS-SD (RFC 6762) and MDNS
     6  // (RFC 6762) specs for local, multicast-DNS-based discovery.
     7  //
     8  // DNSSDService implements the Zone interface and wraps an MDNSService instance.
     9  // To deploy an mDNS service that is compliant with DNS-SD, it's recommended to
    10  // register only the wrapped instance with the server.
    11  //
    12  // Example usage:
    13  //
    14  //	    service := &mdns.DNSSDService{
    15  //	      MDNSService: &mdns.MDNSService{
    16  //		       Instance: "My Foobar Service",
    17  //		       Service: "_foobar._tcp",
    18  //		       Port:    8000,
    19  //	       }
    20  //	     }
    21  //	     server, err := mdns.NewServer(&mdns.Config{Zone: service})
    22  //	     if err != nil {
    23  //	       log.Fatalf("Error creating server: %v", err)
    24  //	     }
    25  //	     defer server.Shutdown()
    26  type DNSSDService struct {
    27  	MDNSService *MDNSService
    28  }
    29  
    30  // Records returns DNS records in response to a DNS question.
    31  //
    32  // This function returns the DNS response of the underlying MDNSService
    33  // instance.  It also returns a PTR record for a request for "
    34  // _services._dns-sd._udp.<Domain>", as described in section 9 of RFC 6763
    35  // ("Service Type Enumeration"), to allow browsing of the underlying MDNSService
    36  // instance.
    37  func (s *DNSSDService) Records(q dns.Question) []dns.RR {
    38  	var recs []dns.RR
    39  	if q.Name == "_services._dns-sd._udp."+s.MDNSService.Domain+"." {
    40  		recs = s.dnssdMetaQueryRecords(q)
    41  	}
    42  	return append(recs, s.MDNSService.Records(q)...)
    43  }
    44  
    45  // dnssdMetaQueryRecords returns the DNS records in response to a "meta-query"
    46  // issued to browse for DNS-SD services, as per section 9. of RFC6763.
    47  //
    48  // A meta-query has a name of the form "_services._dns-sd._udp.<Domain>" where
    49  // Domain is a fully-qualified domain, such as "local.".
    50  func (s *DNSSDService) dnssdMetaQueryRecords(q dns.Question) []dns.RR {
    51  	// Intended behavior, as described in the RFC:
    52  	//     ...it may be useful for network administrators to find the list of
    53  	//     advertised service types on the network, even if those Service Names
    54  	//     are just opaque identifiers and not particularly informative in
    55  	//     isolation.
    56  	//
    57  	//     For this purpose, a special meta-query is defined.  A DNS query for PTR
    58  	//     records with the name "_services._dns-sd._udp.<Domain>" yields a set of
    59  	//     PTR records, where the rdata of each PTR record is the two-abel
    60  	//     <Service> name, plus the same domain, e.g., "_http._tcp.<Domain>".
    61  	//     Including the domain in the PTR rdata allows for slightly better name
    62  	//     compression in Unicast DNS responses, but only the first two labels are
    63  	//     relevant for the purposes of service type enumeration.  These two-label
    64  	//     service types can then be used to construct subsequent Service Instance
    65  	//     Enumeration PTR queries, in this <Domain> or others, to discover
    66  	//     instances of that service type.
    67  	return []dns.RR{
    68  		&dns.PTR{
    69  			Hdr: dns.RR_Header{
    70  				Name:   q.Name,
    71  				Rrtype: dns.TypePTR,
    72  				Class:  dns.ClassINET,
    73  				Ttl:    defaultTTL,
    74  			},
    75  			Ptr: s.MDNSService.serviceAddr,
    76  		},
    77  	}
    78  }
    79  
    80  // Announcement returns DNS records that should be broadcast during the initial
    81  // availability of the service, as described in section 8.3 of RFC 6762.
    82  // TODO(reddaly): Add this when Announcement is added to the mdns.Zone interface.
    83  // func (s *DNSSDService) Announcement() []dns.RR {
    84  //	return s.MDNSService.Announcement()
    85  //}